@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.
Files changed (117) hide show
  1. package/LICENSE +373 -0
  2. package/dist/src/index.d.ts +22 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +25 -0
  5. package/dist/src/index.js.map +1 -0
  6. package/dist/src/render/blocks/accordion.d.ts +4 -0
  7. package/dist/src/render/blocks/accordion.d.ts.map +1 -0
  8. package/dist/src/render/blocks/accordion.js +21 -0
  9. package/dist/src/render/blocks/accordion.js.map +1 -0
  10. package/dist/src/render/blocks/collection-list.d.ts +13 -0
  11. package/dist/src/render/blocks/collection-list.d.ts.map +1 -0
  12. package/dist/src/render/blocks/collection-list.js +109 -0
  13. package/dist/src/render/blocks/collection-list.js.map +1 -0
  14. package/dist/src/render/blocks/cta.d.ts +10 -0
  15. package/dist/src/render/blocks/cta.d.ts.map +1 -0
  16. package/dist/src/render/blocks/cta.js +13 -0
  17. package/dist/src/render/blocks/cta.js.map +1 -0
  18. package/dist/src/render/blocks/embed.d.ts +4 -0
  19. package/dist/src/render/blocks/embed.d.ts.map +1 -0
  20. package/dist/src/render/blocks/embed.js +82 -0
  21. package/dist/src/render/blocks/embed.js.map +1 -0
  22. package/dist/src/render/blocks/faq.d.ts +4 -0
  23. package/dist/src/render/blocks/faq.d.ts.map +1 -0
  24. package/dist/src/render/blocks/faq.js +17 -0
  25. package/dist/src/render/blocks/faq.js.map +1 -0
  26. package/dist/src/render/blocks/feature-grid.d.ts +4 -0
  27. package/dist/src/render/blocks/feature-grid.d.ts.map +1 -0
  28. package/dist/src/render/blocks/feature-grid.js +24 -0
  29. package/dist/src/render/blocks/feature-grid.js.map +1 -0
  30. package/dist/src/render/blocks/gallery.d.ts +11 -0
  31. package/dist/src/render/blocks/gallery.d.ts.map +1 -0
  32. package/dist/src/render/blocks/gallery.js +20 -0
  33. package/dist/src/render/blocks/gallery.js.map +1 -0
  34. package/dist/src/render/blocks/hero.d.ts +16 -0
  35. package/dist/src/render/blocks/hero.d.ts.map +1 -0
  36. package/dist/src/render/blocks/hero.js +32 -0
  37. package/dist/src/render/blocks/hero.js.map +1 -0
  38. package/dist/src/render/blocks/logo-strip.d.ts +4 -0
  39. package/dist/src/render/blocks/logo-strip.d.ts.map +1 -0
  40. package/dist/src/render/blocks/logo-strip.js +16 -0
  41. package/dist/src/render/blocks/logo-strip.js.map +1 -0
  42. package/dist/src/render/blocks/logos.d.ts +4 -0
  43. package/dist/src/render/blocks/logos.d.ts.map +1 -0
  44. package/dist/src/render/blocks/logos.js +23 -0
  45. package/dist/src/render/blocks/logos.js.map +1 -0
  46. package/dist/src/render/blocks/media-figure.d.ts +9 -0
  47. package/dist/src/render/blocks/media-figure.d.ts.map +1 -0
  48. package/dist/src/render/blocks/media-figure.js +24 -0
  49. package/dist/src/render/blocks/media-figure.js.map +1 -0
  50. package/dist/src/render/blocks/pricing-table.d.ts +4 -0
  51. package/dist/src/render/blocks/pricing-table.d.ts.map +1 -0
  52. package/dist/src/render/blocks/pricing-table.js +30 -0
  53. package/dist/src/render/blocks/pricing-table.js.map +1 -0
  54. package/dist/src/render/blocks/prose.d.ts +13 -0
  55. package/dist/src/render/blocks/prose.d.ts.map +1 -0
  56. package/dist/src/render/blocks/prose.js +14 -0
  57. package/dist/src/render/blocks/prose.js.map +1 -0
  58. package/dist/src/render/blocks/quote.d.ts +8 -0
  59. package/dist/src/render/blocks/quote.d.ts.map +1 -0
  60. package/dist/src/render/blocks/quote.js +21 -0
  61. package/dist/src/render/blocks/quote.js.map +1 -0
  62. package/dist/src/render/blocks/stat-counter.d.ts +4 -0
  63. package/dist/src/render/blocks/stat-counter.d.ts.map +1 -0
  64. package/dist/src/render/blocks/stat-counter.js +15 -0
  65. package/dist/src/render/blocks/stat-counter.js.map +1 -0
  66. package/dist/src/render/blocks/stats.d.ts +4 -0
  67. package/dist/src/render/blocks/stats.d.ts.map +1 -0
  68. package/dist/src/render/blocks/stats.js +21 -0
  69. package/dist/src/render/blocks/stats.js.map +1 -0
  70. package/dist/src/render/blocks/testimonial.d.ts +17 -0
  71. package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
  72. package/dist/src/render/blocks/testimonial.js +26 -0
  73. package/dist/src/render/blocks/testimonial.js.map +1 -0
  74. package/dist/src/render/chrome.d.ts +3 -0
  75. package/dist/src/render/chrome.d.ts.map +1 -0
  76. package/dist/src/render/chrome.js +108 -0
  77. package/dist/src/render/chrome.js.map +1 -0
  78. package/dist/src/render/render-block.d.ts +6 -0
  79. package/dist/src/render/render-block.d.ts.map +1 -0
  80. package/dist/src/render/render-block.js +118 -0
  81. package/dist/src/render/render-block.js.map +1 -0
  82. package/dist/src/render/term-archive.d.ts +10 -0
  83. package/dist/src/render/term-archive.d.ts.map +1 -0
  84. package/dist/src/render/term-archive.js +32 -0
  85. package/dist/src/render/term-archive.js.map +1 -0
  86. package/dist/theme.config.d.ts +11 -0
  87. package/dist/theme.config.d.ts.map +1 -0
  88. package/dist/theme.config.js +41 -0
  89. package/dist/theme.config.js.map +1 -0
  90. package/package.json +57 -0
  91. package/src/index.ts +24 -0
  92. package/src/render/blocks/accordion.ts +57 -0
  93. package/src/render/blocks/collection-list.ts +189 -0
  94. package/src/render/blocks/cta.ts +31 -0
  95. package/src/render/blocks/embed.ts +105 -0
  96. package/src/render/blocks/faq.ts +53 -0
  97. package/src/render/blocks/feature-grid.ts +61 -0
  98. package/src/render/blocks/gallery.ts +40 -0
  99. package/src/render/blocks/hero.ts +58 -0
  100. package/src/render/blocks/logo-strip.ts +35 -0
  101. package/src/render/blocks/logos.ts +53 -0
  102. package/src/render/blocks/media-figure.ts +39 -0
  103. package/src/render/blocks/pricing-table.ts +74 -0
  104. package/src/render/blocks/prose.ts +19 -0
  105. package/src/render/blocks/quote.ts +38 -0
  106. package/src/render/blocks/stat-counter.ts +37 -0
  107. package/src/render/blocks/stats.ts +48 -0
  108. package/src/render/blocks/testimonial.ts +42 -0
  109. package/src/render/chrome.ts +141 -0
  110. package/src/render/render-block.ts +156 -0
  111. package/src/render/term-archive.ts +78 -0
  112. package/src/styles/archive.css +84 -0
  113. package/src/styles/base.css +923 -0
  114. package/src/styles/blocks.css +975 -0
  115. package/src/styles/theme.css +36 -0
  116. package/src/styles/tokens.css +320 -0
  117. 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,3 @@
1
+ import { type ChromeInput, type ChromeResult } from '@cogenta/theme-kit';
2
+ export declare function renderChrome(input: ChromeInput): ChromeResult;
3
+ //# sourceMappingURL=chrome.d.ts.map
@@ -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":"AAAA,OAAO,EAAsB,gBAAgB,EAAwB,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EAGL,CAAC,EAED,iBAAiB,EAEjB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,GACjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAI3D,MAAM,UAAU,WAAW,CACzB,KAAsB,EACtB,GAAkB,EAClB,OAAO,GAAmB,EAAE,EAC5B,QAAwB;IAExB,qEAAqE;IACrE,yEAAyE;IACzE,2EAA2E;IAC3E,qEAAqE;IACrE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAA;IACzE,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAClC,MAAM,KAAK,GAAG,QAAsC,CAAA;IACpD,OAAO,gBAAgB,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;AAC/E,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAsB,EACtB,GAAkB,EAClB,OAAuB;IAEvB,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC/B,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChC,KAAK,aAAa;YAChB,OAAO,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACtC,KAAK,aAAa;YAChB,OAAO,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACtC,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC9B,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAClC,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChC,KAAK,KAAK;YACR,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC9B,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChC,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChC,KAAK,gBAAgB;YACnB,OAAO,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QACpE,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChC,KAAK,aAAa;YAChB,OAAO,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACtC,KAAK,cAAc;YACjB,OAAO,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACvC,KAAK,WAAW;YACd,OAAO,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACpC,KAAK,aAAa;YAChB,OAAO,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACtC,KAAK,WAAW;YACd,OAAO,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACpC,SAAS,CAAC;YACR,uEAAuE;YACvE,sEAAsE;YACtE,MAAM;YACN,MAAM,WAAW,GAAU,KAAK,CAAA;YAChC,KAAK,WAAW,CAAA;YAChB,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAC,OAA2B,EAAE,GAAW;IAC5D,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IACjC,OAAO,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,IAAiB,EACjB,GAAkB,EAClB,OAAO,GAAmB,EAAE,EAC5B,QAAwB;IAExB,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5C,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACtF,OAAO,CAAC,CACN,MAAM,EACN,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EACnC,OAAO,EACP,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,YAAY,CACV,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,EACpE,KAAK,CAAC,IAAI,CACX,CACF,CACF,CAAA;AACH,CAAC"}
@@ -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
+ }