@cogenta/theme-restaurant 0.3.2
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/LICENSE +373 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/render/blocks/accordion.d.ts +4 -0
- package/dist/src/render/blocks/accordion.d.ts.map +1 -0
- package/dist/src/render/blocks/accordion.js +21 -0
- package/dist/src/render/blocks/accordion.js.map +1 -0
- package/dist/src/render/blocks/collection-list.d.ts +13 -0
- package/dist/src/render/blocks/collection-list.d.ts.map +1 -0
- package/dist/src/render/blocks/collection-list.js +109 -0
- package/dist/src/render/blocks/collection-list.js.map +1 -0
- package/dist/src/render/blocks/cta.d.ts +10 -0
- package/dist/src/render/blocks/cta.d.ts.map +1 -0
- package/dist/src/render/blocks/cta.js +13 -0
- package/dist/src/render/blocks/cta.js.map +1 -0
- package/dist/src/render/blocks/embed.d.ts +4 -0
- package/dist/src/render/blocks/embed.d.ts.map +1 -0
- package/dist/src/render/blocks/embed.js +82 -0
- package/dist/src/render/blocks/embed.js.map +1 -0
- package/dist/src/render/blocks/faq.d.ts +4 -0
- package/dist/src/render/blocks/faq.d.ts.map +1 -0
- package/dist/src/render/blocks/faq.js +17 -0
- package/dist/src/render/blocks/faq.js.map +1 -0
- package/dist/src/render/blocks/feature-grid.d.ts +4 -0
- package/dist/src/render/blocks/feature-grid.d.ts.map +1 -0
- package/dist/src/render/blocks/feature-grid.js +24 -0
- package/dist/src/render/blocks/feature-grid.js.map +1 -0
- package/dist/src/render/blocks/gallery.d.ts +11 -0
- package/dist/src/render/blocks/gallery.d.ts.map +1 -0
- package/dist/src/render/blocks/gallery.js +20 -0
- package/dist/src/render/blocks/gallery.js.map +1 -0
- package/dist/src/render/blocks/hero.d.ts +16 -0
- package/dist/src/render/blocks/hero.d.ts.map +1 -0
- package/dist/src/render/blocks/hero.js +32 -0
- package/dist/src/render/blocks/hero.js.map +1 -0
- package/dist/src/render/blocks/logo-strip.d.ts +4 -0
- package/dist/src/render/blocks/logo-strip.d.ts.map +1 -0
- package/dist/src/render/blocks/logo-strip.js +16 -0
- package/dist/src/render/blocks/logo-strip.js.map +1 -0
- package/dist/src/render/blocks/logos.d.ts +4 -0
- package/dist/src/render/blocks/logos.d.ts.map +1 -0
- package/dist/src/render/blocks/logos.js +23 -0
- package/dist/src/render/blocks/logos.js.map +1 -0
- package/dist/src/render/blocks/media-figure.d.ts +9 -0
- package/dist/src/render/blocks/media-figure.d.ts.map +1 -0
- package/dist/src/render/blocks/media-figure.js +24 -0
- package/dist/src/render/blocks/media-figure.js.map +1 -0
- package/dist/src/render/blocks/pricing-table.d.ts +4 -0
- package/dist/src/render/blocks/pricing-table.d.ts.map +1 -0
- package/dist/src/render/blocks/pricing-table.js +30 -0
- package/dist/src/render/blocks/pricing-table.js.map +1 -0
- package/dist/src/render/blocks/prose.d.ts +13 -0
- package/dist/src/render/blocks/prose.d.ts.map +1 -0
- package/dist/src/render/blocks/prose.js +14 -0
- package/dist/src/render/blocks/prose.js.map +1 -0
- package/dist/src/render/blocks/quote.d.ts +8 -0
- package/dist/src/render/blocks/quote.d.ts.map +1 -0
- package/dist/src/render/blocks/quote.js +21 -0
- package/dist/src/render/blocks/quote.js.map +1 -0
- package/dist/src/render/blocks/stat-counter.d.ts +4 -0
- package/dist/src/render/blocks/stat-counter.d.ts.map +1 -0
- package/dist/src/render/blocks/stat-counter.js +15 -0
- package/dist/src/render/blocks/stat-counter.js.map +1 -0
- package/dist/src/render/blocks/stats.d.ts +4 -0
- package/dist/src/render/blocks/stats.d.ts.map +1 -0
- package/dist/src/render/blocks/stats.js +21 -0
- package/dist/src/render/blocks/stats.js.map +1 -0
- package/dist/src/render/blocks/testimonial.d.ts +17 -0
- package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
- package/dist/src/render/blocks/testimonial.js +26 -0
- package/dist/src/render/blocks/testimonial.js.map +1 -0
- package/dist/src/render/chrome.d.ts +3 -0
- package/dist/src/render/chrome.d.ts.map +1 -0
- package/dist/src/render/chrome.js +108 -0
- package/dist/src/render/chrome.js.map +1 -0
- package/dist/src/render/render-block.d.ts +6 -0
- package/dist/src/render/render-block.d.ts.map +1 -0
- package/dist/src/render/render-block.js +118 -0
- package/dist/src/render/render-block.js.map +1 -0
- package/dist/src/render/term-archive.d.ts +10 -0
- package/dist/src/render/term-archive.d.ts.map +1 -0
- package/dist/src/render/term-archive.js +32 -0
- package/dist/src/render/term-archive.js.map +1 -0
- package/dist/theme.config.d.ts +11 -0
- package/dist/theme.config.d.ts.map +1 -0
- package/dist/theme.config.js +41 -0
- package/dist/theme.config.js.map +1 -0
- package/package.json +57 -0
- package/src/index.ts +24 -0
- package/src/render/blocks/accordion.ts +57 -0
- package/src/render/blocks/collection-list.ts +189 -0
- package/src/render/blocks/cta.ts +31 -0
- package/src/render/blocks/embed.ts +105 -0
- package/src/render/blocks/faq.ts +53 -0
- package/src/render/blocks/feature-grid.ts +61 -0
- package/src/render/blocks/gallery.ts +40 -0
- package/src/render/blocks/hero.ts +58 -0
- package/src/render/blocks/logo-strip.ts +35 -0
- package/src/render/blocks/logos.ts +53 -0
- package/src/render/blocks/media-figure.ts +39 -0
- package/src/render/blocks/pricing-table.ts +74 -0
- package/src/render/blocks/prose.ts +19 -0
- package/src/render/blocks/quote.ts +38 -0
- package/src/render/blocks/stat-counter.ts +37 -0
- package/src/render/blocks/stats.ts +48 -0
- package/src/render/blocks/testimonial.ts +42 -0
- package/src/render/chrome.ts +141 -0
- package/src/render/render-block.ts +156 -0
- package/src/render/term-archive.ts +78 -0
- package/src/styles/archive.css +84 -0
- package/src/styles/base.css +923 -0
- package/src/styles/blocks.css +975 -0
- package/src/styles/theme.css +36 -0
- package/src/styles/tokens.css +320 -0
- package/tokens.json +36 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TestimonialBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
/**
|
|
4
|
+
* A centred, oversized quotation mark stands above the quote (a CSS
|
|
5
|
+
* pseudo-glyph, not markup) — the guestbook-page treatment this theme's
|
|
6
|
+
* elegance calls for, rather than a bordered "client success" card.
|
|
7
|
+
*
|
|
8
|
+
* `<figure><blockquote>…</blockquote><figcaption>` is the attribution
|
|
9
|
+
* pattern the HTML spec prescribes: putting the author inside the
|
|
10
|
+
* `<blockquote>` would claim the author's name was part of what was said.
|
|
11
|
+
*
|
|
12
|
+
* The avatar is decorative — the name sits right beside it in text — so its
|
|
13
|
+
* media entity's alt text is expected to be empty; `image` still writes the
|
|
14
|
+
* attribute either way (WCAG 1.1.1).
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderTestimonial(block: TestimonialBlock, ctx: RenderContext): HtmlElement;
|
|
17
|
+
//# sourceMappingURL=testimonial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testimonial.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/testimonial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,aAAa,EAAkB,MAAM,oBAAoB,CAAA;AAEnG;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAyB1F"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { h, image, renderRichText } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* A centred, oversized quotation mark stands above the quote (a CSS
|
|
4
|
+
* pseudo-glyph, not markup) — the guestbook-page treatment this theme's
|
|
5
|
+
* elegance calls for, rather than a bordered "client success" card.
|
|
6
|
+
*
|
|
7
|
+
* `<figure><blockquote>…</blockquote><figcaption>` is the attribution
|
|
8
|
+
* pattern the HTML spec prescribes: putting the author inside the
|
|
9
|
+
* `<blockquote>` would claim the author's name was part of what was said.
|
|
10
|
+
*
|
|
11
|
+
* The avatar is decorative — the name sits right beside it in text — so its
|
|
12
|
+
* media entity's alt text is expected to be empty; `image` still writes the
|
|
13
|
+
* attribute either way (WCAG 1.1.1).
|
|
14
|
+
*/
|
|
15
|
+
export function renderTestimonial(block, ctx) {
|
|
16
|
+
const { attribution } = block;
|
|
17
|
+
return h('figure', { class: 'cg-testimonial', 'data-block': 'testimonial' }, h('blockquote', { class: 'cg-testimonial__quote' }, renderRichText(ctx, block.quote)), h('figcaption', { class: 'cg-testimonial__attribution' }, attribution.avatar === undefined
|
|
18
|
+
? null
|
|
19
|
+
: image(ctx, attribution.avatar, {
|
|
20
|
+
className: 'cg-testimonial__avatar',
|
|
21
|
+
variant: { width: 88, height: 88, fit: 'cover' },
|
|
22
|
+
}), h('span', { class: 'cg-testimonial__who' }, h('span', { class: 'cg-testimonial__name' }, attribution.name), attribution.role === undefined
|
|
23
|
+
? null
|
|
24
|
+
: h('span', { class: 'cg-testimonial__role' }, attribution.role))));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=testimonial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testimonial.js","sourceRoot":"","sources":["../../../../src/render/blocks/testimonial.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,CAAC,EAAE,KAAK,EAAsB,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEnG;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAuB,EAAE,GAAkB;IAC3E,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAA;IAC7B,OAAO,CAAC,CACN,QAAQ,EACR,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,EACxD,CAAC,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EACrF,CAAC,CACC,YAAY,EACZ,EAAE,KAAK,EAAE,6BAA6B,EAAE,EACxC,WAAW,CAAC,MAAM,KAAK,SAAS;QAC9B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,MAAM,EAAE;YAC7B,SAAS,EAAE,wBAAwB;YACnC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;SACjD,CAAC,EACN,CAAC,CACC,MAAM,EACN,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAChC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,EAC9D,WAAW,CAAC,IAAI,KAAK,SAAS;QAC5B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,CACnE,CACF,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../../src/render/chrome.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,YAAY,EAOlB,MAAM,oBAAoB,CAAA;AAsE3B,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CA4D7D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { escapeAttribute, escapeText, renderBrandMark, renderSocialLinks, renderThemeToggle, serialize, } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* This theme's own header and footer, built for `theme@1.4` from the start
|
|
4
|
+
* rather than retrofitted: `headerAction` renders as a button beside the
|
|
5
|
+
* primary nav, `tagline`/`social`/`footerNote` fill the footer's brand
|
|
6
|
+
* column, and — the one thing none of the four L23 themes had yet — a
|
|
7
|
+
* genuinely CSS-only mobile menu.
|
|
8
|
+
*
|
|
9
|
+
* The mobile menu is a `<details>`/`<summary>` disclosure, not a checkbox
|
|
10
|
+
* hack: expanding, keyboard operation (`Enter`/`Space` on the `<summary>`)
|
|
11
|
+
* and the open/closed state announced to assistive technology all come from
|
|
12
|
+
* the browser, at zero bytes of JavaScript. It carries the *same* links as
|
|
13
|
+
* the desktop nav plus the header action — never a second, drifting list —
|
|
14
|
+
* and is shown only below the breakpoint `base.css` sets for `.cg-nav`.
|
|
15
|
+
*
|
|
16
|
+
* The manual light/dark toggle (L26) sits right after the desktop nav, before
|
|
17
|
+
* the header action — `renderThemeToggle` (`@cogenta/theme-kit`) returns
|
|
18
|
+
* markup only, this theme styles `.cg-theme-toggle` itself in `base.css`. It
|
|
19
|
+
* is unconditional (rendered on every page, `theme@1.4` fields or not),
|
|
20
|
+
* unlike the header/footer additions above it.
|
|
21
|
+
*/
|
|
22
|
+
function navItems(links) {
|
|
23
|
+
return links
|
|
24
|
+
.filter((link) => link.href !== null || link.kind === 'submenu-placeholder')
|
|
25
|
+
.map((link) => {
|
|
26
|
+
const label = escapeText(link.label);
|
|
27
|
+
const titleAttr = link.title === null ? '' : ` title="${escapeAttribute(link.title)}"`;
|
|
28
|
+
if (link.href === null)
|
|
29
|
+
return `<li><span${titleAttr}>${label}</span></li>`;
|
|
30
|
+
const href = escapeAttribute(link.href);
|
|
31
|
+
const target = link.openInNewTab ? ' target="_blank" rel="noopener"' : '';
|
|
32
|
+
return `<li><a href="${href}"${target}${titleAttr}>${label}</a></li>`;
|
|
33
|
+
})
|
|
34
|
+
.join('');
|
|
35
|
+
}
|
|
36
|
+
/** Three bars, drawn directly rather than pulled from an icon font (R9/R10) — the universal "menu" glyph. */
|
|
37
|
+
const HAMBURGER_GLYPH = '<svg class="cg-mobile-nav__glyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
|
38
|
+
'stroke-width="1.5" stroke-linecap="round" aria-hidden="true" focusable="false">' +
|
|
39
|
+
'<path d="M4 7h16"/><path d="M4 12h16"/><path d="M4 17h16"/></svg>';
|
|
40
|
+
/** The header's own call-to-action link (`theme@1.4`), styled like the block vocabulary's own primary action. */
|
|
41
|
+
function renderHeaderAction(action) {
|
|
42
|
+
if (action === undefined)
|
|
43
|
+
return '';
|
|
44
|
+
return (`<a class="cg-action cg-nav__cta" data-emphasis="primary" ` +
|
|
45
|
+
`href="${escapeAttribute(action.href)}">${escapeText(action.label)}</a>`);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The mobile drawer — the same nav links and header action as the desktop
|
|
49
|
+
* header, in one `<details>` disclosure. Absent entirely when there is
|
|
50
|
+
* nothing to show, exactly like the desktop `<nav>` above it.
|
|
51
|
+
*/
|
|
52
|
+
function renderMobileNav(input) {
|
|
53
|
+
const items = navItems(input.headerNav);
|
|
54
|
+
const actionItem = input.headerAction === undefined ? '' : `<li>${renderHeaderAction(input.headerAction)}</li>`;
|
|
55
|
+
if (items === '' && actionItem === '')
|
|
56
|
+
return '';
|
|
57
|
+
return (`<details class="cg-mobile-nav">` +
|
|
58
|
+
`<summary class="cg-mobile-nav__toggle" aria-label="Menu">${HAMBURGER_GLYPH}</summary>` +
|
|
59
|
+
`<div class="cg-mobile-nav__panel"><ul class="cg-mobile-nav__items">${items}${actionItem}</ul></div>` +
|
|
60
|
+
`</details>`);
|
|
61
|
+
}
|
|
62
|
+
export function renderChrome(input) {
|
|
63
|
+
const siteNameText = escapeText(input.site.name);
|
|
64
|
+
const headerNav = navItems(input.headerNav);
|
|
65
|
+
const footerNav = navItems(input.footerNav);
|
|
66
|
+
// The uploaded logo replaces the wordmark, and only the wordmark: the
|
|
67
|
+
// footer keeps the site's name in text, so a site whose logo fails to
|
|
68
|
+
// load is still named somewhere on every page.
|
|
69
|
+
const mark = renderBrandMark(input.brand, { className: 'cg-site-header__logo' }) ?? siteNameText;
|
|
70
|
+
const themeToggle = serialize(renderThemeToggle(input.locale, { className: 'cg-theme-toggle' }));
|
|
71
|
+
const headerAction = renderHeaderAction(input.headerAction);
|
|
72
|
+
const mobileNav = renderMobileNav(input);
|
|
73
|
+
const header = `<header class="cg-site-header"><div class="cg-site-header__inner">` +
|
|
74
|
+
`<a class="cg-site-header__home" href="${escapeAttribute(input.homeHref)}">${mark}</a>` +
|
|
75
|
+
`${headerNav === ''
|
|
76
|
+
? ''
|
|
77
|
+
: `<nav class="cg-nav" aria-label="Primary"><ul class="cg-nav__items">${headerNav}</ul></nav>`}` +
|
|
78
|
+
`${themeToggle}` +
|
|
79
|
+
`${headerAction}` +
|
|
80
|
+
`${mobileNav}` +
|
|
81
|
+
`</div></header>`;
|
|
82
|
+
const tagline = input.tagline === undefined
|
|
83
|
+
? ''
|
|
84
|
+
: `<p class="cg-site-footer__tagline">${escapeText(input.tagline)}</p>`;
|
|
85
|
+
const social = input.social === undefined
|
|
86
|
+
? ''
|
|
87
|
+
: serialize(renderSocialLinks(input.social, {
|
|
88
|
+
className: 'cg-site-footer__social',
|
|
89
|
+
itemClassName: 'cg-site-footer__social-item',
|
|
90
|
+
}) ?? { kind: 'text', value: '' });
|
|
91
|
+
const footerNote = input.footerNote === undefined
|
|
92
|
+
? ''
|
|
93
|
+
: `<p class="cg-site-footer__note">${escapeText(input.footerNote)}</p>`;
|
|
94
|
+
const footer = `<footer class="cg-site-footer"><div class="cg-site-footer__grid">` +
|
|
95
|
+
`<div class="cg-site-footer__brand">` +
|
|
96
|
+
`<a class="cg-site-footer__brand-name" href="${escapeAttribute(input.homeHref)}">${siteNameText}</a>` +
|
|
97
|
+
`${tagline}${social}</div>` +
|
|
98
|
+
`${footerNav === ''
|
|
99
|
+
? ''
|
|
100
|
+
: `<nav class="cg-site-footer__nav" aria-label="Footer"><ul class="cg-nav__items">${footerNav}</ul></nav>`}` +
|
|
101
|
+
`<div class="cg-site-footer__about">${footerNote}</div>` +
|
|
102
|
+
`</div><div class="cg-site-footer__bottom">` +
|
|
103
|
+
`<span>${siteNameText}</span>` +
|
|
104
|
+
`<div class="cg-site-footer__branding">${input.brandingHtml}</div>` +
|
|
105
|
+
`</div></footer>`;
|
|
106
|
+
return { header, footer };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=chrome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chrome.js","sourceRoot":"","sources":["../../../src/render/chrome.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type BlockRegistry, type VocabularyBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type FetchedEntries, type HtmlElement, type PageContent, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
export type { FetchedEntries, PageContent };
|
|
4
|
+
export declare function renderBlock(block: VocabularyBlock, ctx: RenderContext, entries?: FetchedEntries, registry?: BlockRegistry): HtmlElement | null;
|
|
5
|
+
export declare function renderPage(page: PageContent, ctx: RenderContext, entries?: FetchedEntries, registry?: BlockRegistry): HtmlElement;
|
|
6
|
+
//# sourceMappingURL=render-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-block.d.ts","sourceRoot":"","sources":["../../../src/render/render-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAoB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,WAAW,EAEhB,KAAK,WAAW,EAEhB,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAA;AAmB3B,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,CAAA;AAE3C,wBAAgB,WAAW,CACzB,KAAK,EAAE,eAAe,EACtB,GAAG,EAAE,aAAa,EAClB,OAAO,GAAE,cAAmB,EAC5B,QAAQ,CAAC,EAAE,aAAa,GACvB,WAAW,GAAG,IAAI,CASpB;AAwFD,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,aAAa,EAClB,OAAO,GAAE,cAAmB,EAC5B,QAAQ,CAAC,EAAE,aAAa,GACvB,WAAW,CAeb"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { VOCABULARY_NAMES } from '@cogenta/blocks';
|
|
2
|
+
import { h, pageHasOwnHeading, renderEntryHeader, resolveBlockForRender, withBlockKey, withBlockVariant, } from '@cogenta/theme-kit';
|
|
3
|
+
import { renderAccordion } from './blocks/accordion.js';
|
|
4
|
+
import { renderCollectionList } from './blocks/collection-list.js';
|
|
5
|
+
import { renderCta } from './blocks/cta.js';
|
|
6
|
+
import { renderEmbed } from './blocks/embed.js';
|
|
7
|
+
import { renderFaq } from './blocks/faq.js';
|
|
8
|
+
import { renderFeatureGrid } from './blocks/feature-grid.js';
|
|
9
|
+
import { renderGallery } from './blocks/gallery.js';
|
|
10
|
+
import { renderHero } from './blocks/hero.js';
|
|
11
|
+
import { renderLogoStrip } from './blocks/logo-strip.js';
|
|
12
|
+
import { renderLogos } from './blocks/logos.js';
|
|
13
|
+
import { renderMediaFigure } from './blocks/media-figure.js';
|
|
14
|
+
import { renderPricingTable } from './blocks/pricing-table.js';
|
|
15
|
+
import { renderProse } from './blocks/prose.js';
|
|
16
|
+
import { renderQuote } from './blocks/quote.js';
|
|
17
|
+
import { renderStatCounter } from './blocks/stat-counter.js';
|
|
18
|
+
import { renderStats } from './blocks/stats.js';
|
|
19
|
+
import { renderTestimonial } from './blocks/testimonial.js';
|
|
20
|
+
export function renderBlock(block, ctx, entries = {}, registry) {
|
|
21
|
+
// `block`'s type says `VocabularyBlock`, but the value crossing this
|
|
22
|
+
// boundary from stored content is not always literally one of the shared
|
|
23
|
+
// vocabulary — resolving here is what turns an unimplemented theme-private
|
|
24
|
+
// block into its declared fallback instead of a silently blank slot.
|
|
25
|
+
const resolved = resolveBlockForRender(block, VOCABULARY_NAMES, registry);
|
|
26
|
+
if (resolved === null)
|
|
27
|
+
return null;
|
|
28
|
+
const known = resolved;
|
|
29
|
+
return withBlockVariant(renderKnownBlock(known, ctx, entries), known.variant);
|
|
30
|
+
}
|
|
31
|
+
function renderKnownBlock(known, ctx, entries) {
|
|
32
|
+
switch (known._type) {
|
|
33
|
+
case 'hero':
|
|
34
|
+
return renderHero(known, ctx);
|
|
35
|
+
case 'prose':
|
|
36
|
+
return renderProse(known, ctx);
|
|
37
|
+
case 'mediaFigure':
|
|
38
|
+
return renderMediaFigure(known, ctx);
|
|
39
|
+
case 'featureGrid':
|
|
40
|
+
return renderFeatureGrid(known, ctx);
|
|
41
|
+
case 'cta':
|
|
42
|
+
return renderCta(known, ctx);
|
|
43
|
+
case 'gallery':
|
|
44
|
+
return renderGallery(known, ctx);
|
|
45
|
+
case 'quote':
|
|
46
|
+
return renderQuote(known, ctx);
|
|
47
|
+
case 'faq':
|
|
48
|
+
return renderFaq(known, ctx);
|
|
49
|
+
case 'stats':
|
|
50
|
+
return renderStats(known, ctx);
|
|
51
|
+
case 'logos':
|
|
52
|
+
return renderLogos(known, ctx);
|
|
53
|
+
case 'collectionList':
|
|
54
|
+
return renderCollectionList(known, ctx, entries[known._key] ?? []);
|
|
55
|
+
case 'embed':
|
|
56
|
+
return renderEmbed(known, ctx);
|
|
57
|
+
case 'testimonial':
|
|
58
|
+
return renderTestimonial(known, ctx);
|
|
59
|
+
case 'pricingTable':
|
|
60
|
+
return renderPricingTable(known, ctx);
|
|
61
|
+
case 'accordion':
|
|
62
|
+
return renderAccordion(known, ctx);
|
|
63
|
+
case 'statCounter':
|
|
64
|
+
return renderStatCounter(known, ctx);
|
|
65
|
+
case 'logoStrip':
|
|
66
|
+
return renderLogoStrip(known, ctx);
|
|
67
|
+
default: {
|
|
68
|
+
// Exhaustive over contract B's vocabulary: `known` is `never` here, so
|
|
69
|
+
// a block this package does not implement stops it compiling until it
|
|
70
|
+
// is.
|
|
71
|
+
const unreachable = known;
|
|
72
|
+
void unreachable;
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* `<main id="cg-main">` is mandatory: it is the skip-link's target, written
|
|
79
|
+
* once by `@cogenta/cli`'s `theme-render.ts` outside any theme's control.
|
|
80
|
+
*
|
|
81
|
+
* `withBlockKey` stamps every rendered block with its contract-B `_key` —
|
|
82
|
+
* required so the visual page builder (L16) can map a clicked element in
|
|
83
|
+
* the rendered iframe back to the block that produced it.
|
|
84
|
+
*
|
|
85
|
+
* A routed collection with no `blocks` field of its own — this theme's
|
|
86
|
+
* `menu_item`, in particular — reaches here with an empty block list, so
|
|
87
|
+
* `page.entry` (contract D `theme@1.4`) is what carries its furniture:
|
|
88
|
+
* `renderEntryHeader` draws the title, excerpt (the dish's own
|
|
89
|
+
* `description`, via `entryExcerpt`'s field-name convention) and cover
|
|
90
|
+
* photo. `PageEntryMeta` has no room for a schema-specific field such as
|
|
91
|
+
* `price`/`category`, so a menu item's own page cannot show them without a
|
|
92
|
+
* contract D change — the theme's real, honest limit; the price and
|
|
93
|
+
* category chip the brief also asks for are exactly what the home page's
|
|
94
|
+
* `collectionList` menu already renders for every dish, and the item page
|
|
95
|
+
* still links back there.
|
|
96
|
+
*/
|
|
97
|
+
/**
|
|
98
|
+
* A second, theme-local stamp beside `withBlockKey`'s own `data-block-key`:
|
|
99
|
+
* a real `id` attribute, so this theme's single-page navigation (the
|
|
100
|
+
* blueprint's header/footer links into `#home-menu`/`#home-story`/etc.) has
|
|
101
|
+
* something to scroll to. Contract B's `_key` is already guaranteed unique
|
|
102
|
+
* within one page's block list (the reorder/diff identity every block
|
|
103
|
+
* carries), so reusing it as the DOM id can never collide on a page this
|
|
104
|
+
* theme rendered — safe to do generically, for every block, not only the
|
|
105
|
+
* ones a blueprint happens to link to.
|
|
106
|
+
*/
|
|
107
|
+
function withAnchorId(element, key) {
|
|
108
|
+
if (element === null)
|
|
109
|
+
return null;
|
|
110
|
+
return { ...element, attrs: { ...element.attrs, id: key } };
|
|
111
|
+
}
|
|
112
|
+
export function renderPage(page, ctx, entries = {}, registry) {
|
|
113
|
+
const heading = pageHasOwnHeading(page.blocks)
|
|
114
|
+
? null
|
|
115
|
+
: (renderEntryHeader(page, ctx) ?? h('h1', { class: 'cg-page__title' }, page.title));
|
|
116
|
+
return h('main', { class: 'cg-main', id: 'cg-main' }, heading, page.blocks.map((block) => withAnchorId(withBlockKey(renderBlock(block, ctx, entries, registry), block._key), block._key)));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=render-block.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-block.js","sourceRoot":"","sources":["../../../src/render/render-block.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type HtmlElement, type TermArchiveInput } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The taxonomy-term archive (contract D `theme@1.3`) — a resource index.
|
|
4
|
+
*
|
|
5
|
+
* Built from the same `cg-index__row` rows this theme's `collectionList`
|
|
6
|
+
* dishes would sit in, minus the price column: a date rail on the left,
|
|
7
|
+
* the title and its summary on the right.
|
|
8
|
+
*/
|
|
9
|
+
export declare function renderTermArchive(input: TermArchiveInput): HtmlElement;
|
|
10
|
+
//# sourceMappingURL=term-archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"term-archive.d.ts","sourceRoot":"","sources":["../../../src/render/term-archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAK,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE/E;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAsDtE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { h } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The taxonomy-term archive (contract D `theme@1.3`) — a resource index.
|
|
4
|
+
*
|
|
5
|
+
* Built from the same `cg-index__row` rows this theme's `collectionList`
|
|
6
|
+
* dishes would sit in, minus the price column: a date rail on the left,
|
|
7
|
+
* the title and its summary on the right.
|
|
8
|
+
*/
|
|
9
|
+
export function renderTermArchive(input) {
|
|
10
|
+
const rows = input.entries.map((entry) => h('li', { class: 'cg-index__row' }, entry.publishedAt === null
|
|
11
|
+
? null
|
|
12
|
+
: h('time', { class: 'cg-index__date', datetime: entry.publishedAt }, entry.publishedAt.slice(0, 10)), h('div', { class: 'cg-index__body' }, h('h2', { class: 'cg-index__title' }, entry.href === null
|
|
13
|
+
? entry.title
|
|
14
|
+
: h('a', { class: 'cg-index__link', href: entry.href }, entry.title)), entry.summary === null ? null : h('p', { class: 'cg-index__excerpt' }, entry.summary))));
|
|
15
|
+
return h('main', { class: 'cg-main cg-archive', id: 'cg-main' }, input.ancestors.length === 0
|
|
16
|
+
? null
|
|
17
|
+
: h('nav', { class: 'cg-archive__breadcrumb', 'aria-label': input.labels.breadcrumb }, h('ol', {}, ...input.ancestors.map((l) => h('li', {}, h('a', { href: l.href }, l.label))))), h('h1', { class: 'cg-index__title-heading' }, input.term.label), input.children.length === 0
|
|
18
|
+
? null
|
|
19
|
+
: h('ul', { class: 'cg-archive__children', 'aria-label': input.labels.subterms }, ...input.children.map((c) => h('li', {}, h('a', { href: c.href }, c.label)))), rows.length === 0
|
|
20
|
+
? h('p', { class: 'cg-index__empty' }, input.labels.empty)
|
|
21
|
+
: h('ul', { class: 'cg-index__items' }, ...rows), pager(input));
|
|
22
|
+
}
|
|
23
|
+
function pager(input) {
|
|
24
|
+
if (input.page.previousHref === null && input.page.nextHref === null)
|
|
25
|
+
return null;
|
|
26
|
+
return h('nav', { class: 'cg-archive__pager', 'aria-label': input.labels.pagination }, input.page.previousHref === null
|
|
27
|
+
? null
|
|
28
|
+
: h('a', { rel: 'prev', href: input.page.previousHref }, input.labels.previous), input.page.nextHref === null
|
|
29
|
+
? null
|
|
30
|
+
: h('a', { rel: 'next', href: input.page.nextHref }, input.labels.next));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=term-archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"term-archive.js","sourceRoot":"","sources":["../../../src/render/term-archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract D — Theme, `theme@1.4`.
|
|
3
|
+
*
|
|
4
|
+
* `implements` lists the seventeen blocks of contract B (`blocks@2.0`, RFC
|
|
5
|
+
* 0001) in the order the contract lists them — see
|
|
6
|
+
* `@cogenta/theme-canonical/theme.config.ts` for why that order matters
|
|
7
|
+
* (installation refuses an incomplete theme).
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: import("@cogenta/render").ThemeManifest;
|
|
10
|
+
export default _default;
|
|
11
|
+
//# sourceMappingURL=theme.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.config.d.ts","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { defineTheme } from '@cogenta/render';
|
|
2
|
+
/**
|
|
3
|
+
* Contract D — Theme, `theme@1.4`.
|
|
4
|
+
*
|
|
5
|
+
* `implements` lists the seventeen blocks of contract B (`blocks@2.0`, RFC
|
|
6
|
+
* 0001) in the order the contract lists them — see
|
|
7
|
+
* `@cogenta/theme-canonical/theme.config.ts` for why that order matters
|
|
8
|
+
* (installation refuses an incomplete theme).
|
|
9
|
+
*/
|
|
10
|
+
export default defineTheme({
|
|
11
|
+
name: 'restaurant',
|
|
12
|
+
version: '1.0.0',
|
|
13
|
+
description: 'An elegant, dark-forward restaurant theme: a full-bleed hero, a real priced menu grouped by category, and a genuine dark mode.',
|
|
14
|
+
author: 'Cogenta',
|
|
15
|
+
engine: '^1.0.0',
|
|
16
|
+
blocks: '^2.0.0',
|
|
17
|
+
implements: [
|
|
18
|
+
'hero',
|
|
19
|
+
'prose',
|
|
20
|
+
'mediaFigure',
|
|
21
|
+
'featureGrid',
|
|
22
|
+
'cta',
|
|
23
|
+
'gallery',
|
|
24
|
+
'quote',
|
|
25
|
+
'faq',
|
|
26
|
+
'stats',
|
|
27
|
+
'logos',
|
|
28
|
+
'collectionList',
|
|
29
|
+
'embed',
|
|
30
|
+
'testimonial',
|
|
31
|
+
'pricingTable',
|
|
32
|
+
'accordion',
|
|
33
|
+
'statCounter',
|
|
34
|
+
'logoStrip',
|
|
35
|
+
],
|
|
36
|
+
collections: ['menu_item', 'page'],
|
|
37
|
+
runtime: 'static',
|
|
38
|
+
tokens: './tokens.json',
|
|
39
|
+
a11y: { verified: 'WCAG-2.2-AA' },
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=theme.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.config.js","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C;;;;;;;GAOG;AACH,eAAe,WAAW,CAAC;IACzB,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;IAChB,WAAW,EACT,gIAAgI;IAClI,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE;QACV,MAAM;QACN,OAAO;QACP,aAAa;QACb,aAAa;QACb,KAAK;QACL,SAAS;QACT,OAAO;QACP,KAAK;QACL,OAAO;QACP,OAAO;QACP,gBAAgB;QAChB,OAAO;QACP,aAAa;QACb,cAAc;QACd,WAAW;QACX,aAAa;QACb,WAAW;KACZ;IACD,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;IAClC,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;CAClC,CAAC,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cogenta/theme-restaurant",
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "An elegant, dark-forward Cogenta theme for restaurants: a full-bleed hero, a real priced menu grouped by category, and a genuine dark mode.",
|
|
5
|
+
"license": "MPL-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/src/index.d.ts",
|
|
11
|
+
"default": "./dist/src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./theme.config": {
|
|
14
|
+
"types": "./dist/theme.config.d.ts",
|
|
15
|
+
"default": "./dist/theme.config.js"
|
|
16
|
+
},
|
|
17
|
+
"./tokens.json": "./tokens.json",
|
|
18
|
+
"./styles/theme.css": "./src/styles/theme.css",
|
|
19
|
+
"./styles/*.css": "./src/styles/*.css"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"src",
|
|
24
|
+
"tokens.json"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=22.11.0"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"provenance": true
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/cogenta-cms/cogenta.git",
|
|
36
|
+
"directory": "packages/theme-restaurant"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@cogenta/blocks": "1.0.3",
|
|
40
|
+
"@cogenta/render": "0.2.3",
|
|
41
|
+
"@cogenta/theme-kit": "0.3.2"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"astro": "^7.2.1"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"astro": "^7.2.1",
|
|
48
|
+
"typescript": "^7.0.2",
|
|
49
|
+
"vitest": "^4.1.10"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc -p tsconfig.json",
|
|
53
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
54
|
+
"test": "vitest run --passWithNoTests",
|
|
55
|
+
"test:integration": "vitest run --config vitest.integration.config.ts --passWithNoTests"
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// The shared contract D primitives every theme package implements against —
|
|
2
|
+
// re-exported so a consumer of this package never has to know they live in
|
|
3
|
+
// `@cogenta/theme-kit` to use them alongside this theme's own blocks.
|
|
4
|
+
export * from '@cogenta/theme-kit'
|
|
5
|
+
export * from './render/blocks/accordion.js'
|
|
6
|
+
export * from './render/blocks/collection-list.js'
|
|
7
|
+
export * from './render/blocks/cta.js'
|
|
8
|
+
export * from './render/blocks/embed.js'
|
|
9
|
+
export * from './render/blocks/faq.js'
|
|
10
|
+
export * from './render/blocks/feature-grid.js'
|
|
11
|
+
export * from './render/blocks/gallery.js'
|
|
12
|
+
export * from './render/blocks/hero.js'
|
|
13
|
+
export * from './render/blocks/logo-strip.js'
|
|
14
|
+
export * from './render/blocks/logos.js'
|
|
15
|
+
export * from './render/blocks/media-figure.js'
|
|
16
|
+
export * from './render/blocks/pricing-table.js'
|
|
17
|
+
export * from './render/blocks/prose.js'
|
|
18
|
+
export * from './render/blocks/quote.js'
|
|
19
|
+
export * from './render/blocks/stat-counter.js'
|
|
20
|
+
export * from './render/blocks/stats.js'
|
|
21
|
+
export * from './render/blocks/testimonial.js'
|
|
22
|
+
export * from './render/chrome.js'
|
|
23
|
+
export * from './render/render-block.js'
|
|
24
|
+
export * from './render/term-archive.js'
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AccordionBlock, AccordionItem } from '@cogenta/blocks'
|
|
2
|
+
import {
|
|
3
|
+
blockHeadingTag,
|
|
4
|
+
type HtmlElement,
|
|
5
|
+
h,
|
|
6
|
+
heading,
|
|
7
|
+
type RenderContext,
|
|
8
|
+
renderRichText,
|
|
9
|
+
} from '@cogenta/theme-kit'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* `blocks@2.0` (RFC 0001). `<details>`/`<summary>` — expanding, keyboard
|
|
13
|
+
* operation and the expanded state announced to assistive technology all
|
|
14
|
+
* come from the browser, at zero bytes of JavaScript. This theme's own
|
|
15
|
+
* blueprint uses it for "Hours & location": opening hours as a small table,
|
|
16
|
+
* the address, and parking — three panels a diner opens one at a time
|
|
17
|
+
* rather than a wall of text under the menu.
|
|
18
|
+
*
|
|
19
|
+
* A thin plus/minus mark, drawn from two CSS borders rather than an icon
|
|
20
|
+
* font, rotates to a single line when the panel is open.
|
|
21
|
+
*/
|
|
22
|
+
function renderItem(item: AccordionItem, ctx: RenderContext): HtmlElement {
|
|
23
|
+
return h(
|
|
24
|
+
'li',
|
|
25
|
+
{ class: 'cg-hours__item' },
|
|
26
|
+
h(
|
|
27
|
+
'details',
|
|
28
|
+
{ class: 'cg-hours__details' },
|
|
29
|
+
h(
|
|
30
|
+
'summary',
|
|
31
|
+
{ class: 'cg-hours__question' },
|
|
32
|
+
h('span', { class: 'cg-hours__question-text' }, item.question),
|
|
33
|
+
h('span', { class: 'cg-hours__mark', 'aria-hidden': 'true' }),
|
|
34
|
+
),
|
|
35
|
+
h('div', { class: 'cg-hours__answer' }, renderRichText(ctx, item.answer)),
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function renderAccordion(block: AccordionBlock, ctx: RenderContext): HtmlElement {
|
|
41
|
+
return h(
|
|
42
|
+
'section',
|
|
43
|
+
{ class: 'cg-hours', 'data-block': 'accordion' },
|
|
44
|
+
block.title === undefined
|
|
45
|
+
? null
|
|
46
|
+
: heading(
|
|
47
|
+
blockHeadingTag('accordion') ?? 'h2',
|
|
48
|
+
{ class: 'cg-hours__title', 'data-field': 'title' },
|
|
49
|
+
block.title,
|
|
50
|
+
),
|
|
51
|
+
h(
|
|
52
|
+
'ul',
|
|
53
|
+
{ class: 'cg-hours__items' },
|
|
54
|
+
block.items.map((item) => renderItem(item, ctx)),
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
}
|