@cogenta/theme-association 0.3.2 → 0.5.3

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 (148) hide show
  1. package/dist/src/index.d.ts +6 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +9 -0
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/render/blocks/accordion.d.ts.map +1 -1
  6. package/dist/src/render/blocks/accordion.js +13 -10
  7. package/dist/src/render/blocks/accordion.js.map +1 -1
  8. package/dist/src/render/blocks/breakdown.d.ts +14 -0
  9. package/dist/src/render/blocks/breakdown.d.ts.map +1 -0
  10. package/dist/src/render/blocks/breakdown.js +17 -0
  11. package/dist/src/render/blocks/breakdown.js.map +1 -0
  12. package/dist/src/render/blocks/collection-list.d.ts +4 -10
  13. package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
  14. package/dist/src/render/blocks/collection-list.js +89 -58
  15. package/dist/src/render/blocks/collection-list.js.map +1 -1
  16. package/dist/src/render/blocks/cta.d.ts +0 -5
  17. package/dist/src/render/blocks/cta.d.ts.map +1 -1
  18. package/dist/src/render/blocks/cta.js +22 -10
  19. package/dist/src/render/blocks/cta.js.map +1 -1
  20. package/dist/src/render/blocks/embed.d.ts.map +1 -1
  21. package/dist/src/render/blocks/embed.js +30 -22
  22. package/dist/src/render/blocks/embed.js.map +1 -1
  23. package/dist/src/render/blocks/faq.d.ts.map +1 -1
  24. package/dist/src/render/blocks/faq.js +11 -15
  25. package/dist/src/render/blocks/faq.js.map +1 -1
  26. package/dist/src/render/blocks/feature-grid.d.ts +6 -0
  27. package/dist/src/render/blocks/feature-grid.d.ts.map +1 -1
  28. package/dist/src/render/blocks/feature-grid.js +42 -20
  29. package/dist/src/render/blocks/feature-grid.js.map +1 -1
  30. package/dist/src/render/blocks/gallery.d.ts +9 -7
  31. package/dist/src/render/blocks/gallery.d.ts.map +1 -1
  32. package/dist/src/render/blocks/gallery.js +22 -16
  33. package/dist/src/render/blocks/gallery.js.map +1 -1
  34. package/dist/src/render/blocks/hero.d.ts +23 -9
  35. package/dist/src/render/blocks/hero.d.ts.map +1 -1
  36. package/dist/src/render/blocks/hero.js +40 -23
  37. package/dist/src/render/blocks/hero.js.map +1 -1
  38. package/dist/src/render/blocks/logo-strip.d.ts +6 -0
  39. package/dist/src/render/blocks/logo-strip.d.ts.map +1 -1
  40. package/dist/src/render/blocks/logo-strip.js +7 -9
  41. package/dist/src/render/blocks/logo-strip.js.map +1 -1
  42. package/dist/src/render/blocks/logos.d.ts +14 -0
  43. package/dist/src/render/blocks/logos.d.ts.map +1 -1
  44. package/dist/src/render/blocks/logos.js +30 -16
  45. package/dist/src/render/blocks/logos.js.map +1 -1
  46. package/dist/src/render/blocks/media-figure.d.ts +12 -5
  47. package/dist/src/render/blocks/media-figure.d.ts.map +1 -1
  48. package/dist/src/render/blocks/media-figure.js +32 -18
  49. package/dist/src/render/blocks/media-figure.js.map +1 -1
  50. package/dist/src/render/blocks/pricing-table.d.ts.map +1 -1
  51. package/dist/src/render/blocks/pricing-table.js +18 -20
  52. package/dist/src/render/blocks/pricing-table.js.map +1 -1
  53. package/dist/src/render/blocks/prose.d.ts +9 -3
  54. package/dist/src/render/blocks/prose.d.ts.map +1 -1
  55. package/dist/src/render/blocks/prose.js +11 -4
  56. package/dist/src/render/blocks/prose.js.map +1 -1
  57. package/dist/src/render/blocks/quote.d.ts +4 -7
  58. package/dist/src/render/blocks/quote.d.ts.map +1 -1
  59. package/dist/src/render/blocks/quote.js +12 -17
  60. package/dist/src/render/blocks/quote.js.map +1 -1
  61. package/dist/src/render/blocks/stat-counter.d.ts +8 -1
  62. package/dist/src/render/blocks/stat-counter.d.ts.map +1 -1
  63. package/dist/src/render/blocks/stat-counter.js +18 -10
  64. package/dist/src/render/blocks/stat-counter.js.map +1 -1
  65. package/dist/src/render/blocks/stats.d.ts +12 -1
  66. package/dist/src/render/blocks/stats.d.ts.map +1 -1
  67. package/dist/src/render/blocks/stats.js +24 -14
  68. package/dist/src/render/blocks/stats.js.map +1 -1
  69. package/dist/src/render/blocks/testimonial.d.ts +6 -5
  70. package/dist/src/render/blocks/testimonial.d.ts.map +1 -1
  71. package/dist/src/render/blocks/testimonial.js +13 -11
  72. package/dist/src/render/blocks/testimonial.js.map +1 -1
  73. package/dist/src/render/chrome.d.ts +38 -1
  74. package/dist/src/render/chrome.d.ts.map +1 -1
  75. package/dist/src/render/chrome.js +117 -91
  76. package/dist/src/render/chrome.js.map +1 -1
  77. package/dist/src/render/details.d.ts +79 -0
  78. package/dist/src/render/details.d.ts.map +1 -0
  79. package/dist/src/render/details.js +221 -0
  80. package/dist/src/render/details.js.map +1 -0
  81. package/dist/src/render/figures.d.ts +29 -0
  82. package/dist/src/render/figures.d.ts.map +1 -0
  83. package/dist/src/render/figures.js +59 -0
  84. package/dist/src/render/figures.js.map +1 -0
  85. package/dist/src/render/layout.d.ts +31 -0
  86. package/dist/src/render/layout.d.ts.map +1 -0
  87. package/dist/src/render/layout.js +46 -0
  88. package/dist/src/render/layout.js.map +1 -0
  89. package/dist/src/render/page-head.d.ts +7 -0
  90. package/dist/src/render/page-head.d.ts.map +1 -0
  91. package/dist/src/render/page-head.js +95 -0
  92. package/dist/src/render/page-head.js.map +1 -0
  93. package/dist/src/render/render-block.d.ts +8 -12
  94. package/dist/src/render/render-block.d.ts.map +1 -1
  95. package/dist/src/render/render-block.js +40 -29
  96. package/dist/src/render/render-block.js.map +1 -1
  97. package/dist/src/render/strings.d.ts +15 -0
  98. package/dist/src/render/strings.d.ts.map +1 -0
  99. package/dist/src/render/strings.js +39 -0
  100. package/dist/src/render/strings.js.map +1 -0
  101. package/dist/src/render/term-archive.d.ts.map +1 -1
  102. package/dist/src/render/term-archive.js +33 -25
  103. package/dist/src/render/term-archive.js.map +1 -1
  104. package/dist/src/render/widget-areas.d.ts +14 -0
  105. package/dist/src/render/widget-areas.d.ts.map +1 -0
  106. package/dist/src/render/widget-areas.js +21 -0
  107. package/dist/src/render/widget-areas.js.map +1 -0
  108. package/dist/theme.config.d.ts +1 -1
  109. package/dist/theme.config.js +3 -3
  110. package/dist/theme.config.js.map +1 -1
  111. package/package.json +5 -5
  112. package/src/index.ts +9 -0
  113. package/src/render/blocks/accordion.ts +28 -22
  114. package/src/render/blocks/breakdown.ts +42 -0
  115. package/src/render/blocks/collection-list.ts +234 -103
  116. package/src/render/blocks/cta.ts +48 -19
  117. package/src/render/blocks/embed.ts +47 -29
  118. package/src/render/blocks/faq.ts +22 -31
  119. package/src/render/blocks/feature-grid.ts +73 -41
  120. package/src/render/blocks/gallery.ts +32 -26
  121. package/src/render/blocks/hero.ts +56 -43
  122. package/src/render/blocks/logo-strip.ts +23 -21
  123. package/src/render/blocks/logos.ts +45 -40
  124. package/src/render/blocks/media-figure.ts +49 -24
  125. package/src/render/blocks/pricing-table.ts +31 -40
  126. package/src/render/blocks/prose.ts +16 -6
  127. package/src/render/blocks/quote.ts +34 -27
  128. package/src/render/blocks/stat-counter.ts +35 -29
  129. package/src/render/blocks/stats.ts +46 -38
  130. package/src/render/blocks/testimonial.ts +29 -20
  131. package/src/render/chrome.ts +165 -91
  132. package/src/render/details.ts +276 -0
  133. package/src/render/figures.ts +68 -0
  134. package/src/render/layout.ts +78 -0
  135. package/src/render/page-head.ts +193 -0
  136. package/src/render/render-block.ts +45 -32
  137. package/src/render/strings.ts +74 -0
  138. package/src/render/term-archive.ts +94 -58
  139. package/src/render/widget-areas.ts +24 -0
  140. package/src/styles/archive.css +38 -102
  141. package/src/styles/base.css +503 -554
  142. package/src/styles/blocks.css +913 -666
  143. package/src/styles/chrome.css +506 -0
  144. package/src/styles/listings.css +591 -0
  145. package/src/styles/theme.css +25 -19
  146. package/src/styles/tokens.css +284 -234
  147. package/src/styles/widgets.css +1059 -0
  148. package/tokens.json +18 -18
@@ -1 +1 @@
1
- {"version":3,"file":"term-archive.js","sourceRoot":"","sources":["../../../src/render/term-archive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"term-archive.js","sourceRoot":"","sources":["../../../src/render/term-archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The widget areas this theme names (contract D `theme@1.6`). Declaring them
3
+ * is what tells the host this theme draws the footer columns inside its own
4
+ * green band; the page areas are placed by the host in the shared
5
+ * `cg-sidebar-layout` markup, which `styles/widgets.css` sets as the side
6
+ * column of a noticeboard: short labels, ruled lists, photographs, and the
7
+ * ask on the paper band.
8
+ */
9
+ export declare const widgetAreas: readonly {
10
+ readonly id: string;
11
+ readonly label: string;
12
+ readonly description?: string;
13
+ }[];
14
+ //# sourceMappingURL=widget-areas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-areas.d.ts","sourceRoot":"","sources":["../../../src/render/widget-areas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B,EAWA,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The widget areas this theme names (contract D `theme@1.6`). Declaring them
3
+ * is what tells the host this theme draws the footer columns inside its own
4
+ * green band; the page areas are placed by the host in the shared
5
+ * `cg-sidebar-layout` markup, which `styles/widgets.css` sets as the side
6
+ * column of a noticeboard: short labels, ruled lists, photographs, and the
7
+ * ask on the paper band.
8
+ */
9
+ export const widgetAreas = [
10
+ {
11
+ id: 'sidebar',
12
+ label: 'Side column',
13
+ description: 'Beside an event, a programme and search results.',
14
+ },
15
+ {
16
+ id: 'content-after',
17
+ label: 'Under the page',
18
+ description: 'After an event, a programme or a page, before the comments.',
19
+ },
20
+ ];
21
+ //# sourceMappingURL=widget-areas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-areas.js","sourceRoot":"","sources":["../../../src/render/widget-areas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAIlB;IACJ;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,kDAAkD;KAChE;IACD;QACE,EAAE,EAAE,eAAe;QACnB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,6DAA6D;KAC3E;CACF,CAAA"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Contract D — Thème, `theme@1.4`.
2
+ * Contract D — Thème, `theme@1.5`.
3
3
  *
4
4
  * `implements` lists the seventeen blocks of contract B (`blocks@2.0`, RFC
5
5
  * 0001) in the order the contract lists them — installation refuses an
@@ -1,6 +1,6 @@
1
1
  import { defineTheme } from '@cogenta/render';
2
2
  /**
3
- * Contract D — Thème, `theme@1.4`.
3
+ * Contract D — Thème, `theme@1.5`.
4
4
  *
5
5
  * `implements` lists the seventeen blocks of contract B (`blocks@2.0`, RFC
6
6
  * 0001) in the order the contract lists them — installation refuses an
@@ -14,7 +14,7 @@ import { defineTheme } from '@cogenta/render';
14
14
  export default defineTheme({
15
15
  name: 'association',
16
16
  version: '1.0.0',
17
- description: 'A warm, human theme for a nonprofit or community group: dated event cards, an impact band, and a genuine dark mode.',
17
+ description: 'A neighbourhood charity: a photograph of the people it works with, impact figures with their context, programmes, a dated events calendar with event pages, and a donation ask in its own yellow.',
18
18
  author: 'Cogenta',
19
19
  engine: '^1.0.0',
20
20
  blocks: '^2.0.0',
@@ -37,7 +37,7 @@ export default defineTheme({
37
37
  'statCounter',
38
38
  'logoStrip',
39
39
  ],
40
- collections: ['event', 'page'],
40
+ collections: ['event', 'programme', 'page'],
41
41
  runtime: 'static',
42
42
  tokens: './tokens.json',
43
43
  a11y: { verified: 'WCAG-2.2-AA' },
@@ -1 +1 @@
1
- {"version":3,"file":"theme.config.js","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C;;;;;;;;;;;GAWG;AACH,eAAe,WAAW,CAAC;IACzB,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;IAChB,WAAW,EACT,qHAAqH;IACvH,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,OAAO,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;CAClC,CAAC,CAAA"}
1
+ {"version":3,"file":"theme.config.js","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C;;;;;;;;;;;GAWG;AACH,eAAe,WAAW,CAAC;IACzB,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;IAChB,WAAW,EACT,mMAAmM;IACrM,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,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC;IAC3C,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;CAClC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cogenta/theme-association",
3
- "version": "0.3.2",
4
- "description": "A warm, human theme for a nonprofit or association: dated event cards, an impact band, and a genuine dark mode, with zero client JavaScript.",
3
+ "version": "0.5.3",
4
+ "description": "A Cogenta theme for a neighbourhood charity: a photograph of the people it works with, impact figures with their context, programmes, a dated events calendar with event pages, a donation ask in its own yellow, and a designed dark mode.",
5
5
  "license": "MPL-2.0",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -36,9 +36,9 @@
36
36
  "directory": "packages/theme-association"
37
37
  },
38
38
  "dependencies": {
39
- "@cogenta/blocks": "1.0.3",
40
- "@cogenta/render": "0.2.3",
41
- "@cogenta/theme-kit": "0.3.2"
39
+ "@cogenta/blocks": "1.1.3",
40
+ "@cogenta/render": "0.3.5",
41
+ "@cogenta/theme-kit": "0.5.3"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "astro": "^7.2.1"
package/src/index.ts CHANGED
@@ -1,4 +1,9 @@
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'
1
5
  export * from './render/blocks/accordion.js'
6
+ export * from './render/blocks/breakdown.js'
2
7
  export * from './render/blocks/collection-list.js'
3
8
  export * from './render/blocks/cta.js'
4
9
  export * from './render/blocks/embed.js'
@@ -16,5 +21,9 @@ export * from './render/blocks/stat-counter.js'
16
21
  export * from './render/blocks/stats.js'
17
22
  export * from './render/blocks/testimonial.js'
18
23
  export * from './render/chrome.js'
24
+ export * from './render/details.js'
25
+ export * from './render/figures.js'
26
+ export * from './render/page-head.js'
19
27
  export * from './render/render-block.js'
20
28
  export * from './render/term-archive.js'
29
+ export * from './render/widget-areas.js'
@@ -1,47 +1,53 @@
1
1
  import type { AccordionBlock, AccordionItem } from '@cogenta/blocks'
2
2
  import {
3
- blockHeadingTag,
4
3
  type HtmlElement,
5
4
  h,
6
- heading,
5
+ nestedHeadingTag,
7
6
  type RenderContext,
8
7
  renderRichText,
9
8
  } from '@cogenta/theme-kit'
9
+ import { section, sectionHead } from '../layout.js'
10
10
 
11
11
  /**
12
- * `blocks@2.0` (RFC 0001). Shares `faq`'s `<details>`/`<summary>` mechanics —
13
- * the same zero-JavaScript disclosure this theme's own mobile nav toggle
14
- * uses — but is its own block, since "accordion" and "frequently asked
15
- * question" are different editorial intents even when the shape coincides.
12
+ * Notes a visitor opens when they need them: what to bring, parking, the
13
+ * safeguarding check. The title on the first four columns and the rows on the
14
+ * last eight, each row a `<details>` under a hairline. It opens without a
15
+ * script and is found by the browser's own search. The question sits in a
16
+ * real heading inside the summary, so a screen reader's heading list still
17
+ * reaches every one. The plus that becomes a minus is two bars drawn by the
18
+ * stylesheet, not a glyph.
16
19
  */
17
- function renderItem(item: AccordionItem, ctx: RenderContext): HtmlElement {
20
+ function row(item: AccordionItem, ctx: RenderContext, titled: boolean): HtmlElement {
18
21
  return h(
19
22
  'li',
20
- { class: 'cg-accordion__item' },
23
+ { class: 'ca-notes__item' },
21
24
  h(
22
25
  'details',
23
- { class: 'cg-accordion__details' },
24
- h('summary', { class: 'cg-accordion__question' }, item.question),
25
- h('div', { class: 'cg-accordion__answer' }, renderRichText(ctx, item.answer)),
26
+ { class: 'ca-notes__details' },
27
+ h(
28
+ 'summary',
29
+ { class: 'ca-notes__summary' },
30
+ h(nestedHeadingTag('accordion', titled), { class: 'ca-notes__question' }, item.question),
31
+ h('span', { class: 'ca-notes__mark', 'aria-hidden': 'true' }),
32
+ ),
33
+ h('div', { class: 'ca-notes__answer' }, renderRichText(ctx, item.answer)),
26
34
  ),
27
35
  )
28
36
  }
29
37
 
30
38
  export function renderAccordion(block: AccordionBlock, ctx: RenderContext): HtmlElement {
31
- return h(
39
+ const titled = block.title !== undefined
40
+ return section(
32
41
  'section',
33
- { class: 'cg-block cg-accordion', 'data-block': 'accordion' },
34
- block.title === undefined
35
- ? null
36
- : heading(
37
- blockHeadingTag('accordion') ?? 'h2',
38
- { class: 'cg-accordion__title', 'data-field': 'title' },
39
- block.title,
40
- ),
42
+ 'accordion',
43
+ 'ca-notes',
44
+ { 'data-titled': String(titled) },
45
+ 'div',
46
+ sectionHead('accordion', block.title),
41
47
  h(
42
48
  'ul',
43
- { class: 'cg-accordion__items' },
44
- block.items.map((item) => renderItem(item, ctx)),
49
+ { class: 'ca-notes__items' },
50
+ block.items.map((item) => row(item, ctx, titled)),
45
51
  ),
46
52
  )
47
53
  }
@@ -0,0 +1,42 @@
1
+ import { type HtmlElement, h, type RenderContext } from '@cogenta/theme-kit'
2
+ import { shareOf } from '../figures.js'
3
+ import { associationString } from '../strings.js'
4
+
5
+ /**
6
+ * Where the money goes, as shares of one total: one row per share, the
7
+ * percentage in tabular figures, what it pays for, and a bar under it as long
8
+ * as the share. The bar is a presentational `<span>` whose length is the
9
+ * number beside it, so nothing is said twice to a screen reader; the figure
10
+ * itself is a `<data>` element carrying the exact value.
11
+ */
12
+ export function renderBreakdown(
13
+ items: readonly {
14
+ readonly value: string
15
+ readonly unit?: string | undefined
16
+ readonly label: string
17
+ }[],
18
+ ctx: RenderContext,
19
+ ): HtmlElement {
20
+ return h(
21
+ 'dl',
22
+ { class: 'ca-shares', 'aria-label': associationString(ctx.locale, 'share') },
23
+ items.map((item) => {
24
+ const share = shareOf(item.value, item.unit) ?? 0
25
+ return h(
26
+ 'div',
27
+ { class: 'ca-shares__item' },
28
+ h('dt', { class: 'ca-shares__label' }, item.label),
29
+ h(
30
+ 'dd',
31
+ { class: 'ca-shares__value' },
32
+ h('data', { value: String(share) }, `${item.value}${item.unit ?? ''}`),
33
+ ),
34
+ h(
35
+ 'dd',
36
+ { class: 'ca-shares__track', 'aria-hidden': 'true' },
37
+ h('span', { class: 'ca-shares__bar', style: `inline-size:${share}%` }),
38
+ ),
39
+ )
40
+ }),
41
+ )
42
+ }
@@ -1,6 +1,5 @@
1
1
  import type { CollectionListBlock } from '@cogenta/blocks'
2
2
  import {
3
- blockHeadingTag,
4
3
  buildCollectionListQuery,
5
4
  type ContentEntry,
6
5
  entryExcerpt,
@@ -12,133 +11,265 @@ import {
12
11
  h,
13
12
  heading,
14
13
  nestedHeadingTag,
14
+ type QueryRequest,
15
15
  type RenderContext,
16
16
  renderImageSource,
17
17
  } from '@cogenta/theme-kit'
18
+ import {
19
+ type EventTime,
20
+ eventTimeOf,
21
+ factsOf,
22
+ hoursOf,
23
+ placeOf,
24
+ renderDateBlock,
25
+ renderFacts,
26
+ textOf,
27
+ } from '../details.js'
28
+ import { section, sectionHead } from '../layout.js'
18
29
 
19
30
  /**
20
- * The only block of the seventeen that reads data at render time — contract
21
- * B marks it `runtime: 'server'` for that reason. The read is *not* done
22
- * here: `query` builds the request from the block's own fields, the caller
23
- * awaits `ctx.content.list(...)` before rendering starts, and this function
24
- * stays a pure function of the entries handed to it.
31
+ * A list of entries, read by what the entries are rather than by a setting.
32
+ *
33
+ * - **Events.** Every entry carries a date (`eventTimeOf`), so this is a
34
+ * calendar, and it reads in date order whatever order the entries arrived
35
+ * in. `list` sets one event per row under a hairline: the date block (the
36
+ * month in small capitals, the day large, the weekday) on the first two
37
+ * columns, the title, the hours and the place, and the entry's summary;
38
+ * what it costs on the right. `grid` sets the same events three to a row
39
+ * under a rule; `carousel` in a row that scrolls sideways.
40
+ * - **Programmes and stories with photographs.** Every entry has a picture.
41
+ * `list` alternates rows of picture and words, the picture a 4:5 crop on
42
+ * four columns, first on the left, then on the right; the words carry the
43
+ * entry's schedule in the organisation's green, its title, its summary and
44
+ * where it happens. `grid` sets the same entries three to a row;
45
+ * `carousel` in a row that scrolls sideways.
46
+ * - **An index.** Anything else: ruled rows of titles and their summaries.
47
+ *
48
+ * The page an entry is shown on is never listed on itself: "more events" on
49
+ * an event's own page skips the event above it.
50
+ *
51
+ * Each picture repeats the link of its title, so it is taken out of the tab
52
+ * order and hidden from assistive technology: one link per entry is
53
+ * announced, the title.
25
54
  */
26
- export { buildCollectionListQuery as query }
27
55
 
28
- /** A string field, read straight off the raw entry — never invented. */
29
- function stringField(entry: ContentEntry, field: string): string | undefined {
30
- const value = entry[field]
31
- return typeof value === 'string' && value.trim() !== '' ? value : undefined
56
+ type Shape = 'events' | 'rows' | 'photos' | 'index'
57
+
58
+ function shapeOf(
59
+ entries: readonly ContentEntry[],
60
+ ctx: RenderContext,
61
+ layout: CollectionListBlock['layout'],
62
+ ): Shape {
63
+ if (entries.every((entry) => eventTimeOf(entry) !== undefined)) return 'events'
64
+ if (entries.every((entry) => entryImage(entry, ctx) !== undefined)) {
65
+ return layout === 'list' ? 'rows' : 'photos'
66
+ }
67
+ return 'index'
32
68
  }
33
69
 
34
- /**
35
- * "Upcoming events" cards are what this block is built around: a rounded,
36
- * shadowed card whose left edge carries a big day/month badge, built
37
- * straight from the entry's own `date` field when it has one — never from
38
- * `entryDate` (which reads `publishedAt`/`createdAt`, a system field with a
39
- * different meaning for an event than the date it actually happens on).
40
- * `location` is read the same direct way, since it too is a schema field no
41
- * shared helper names.
42
- *
43
- * An entry from a collection with neither `date` nor `location` — any other
44
- * collection a site points a `collectionList` at — falls back to the same
45
- * title/excerpt/cover row every other theme's list block shows, so this
46
- * block stays generically usable, not association-only.
47
- */
48
- function renderEntry(entry: ContentEntry, ctx: RenderContext, tag: HeadingTag): HtmlElement {
49
- const rawDate = stringField(entry, 'date')
50
- const parsed = rawDate === undefined ? null : new Date(rawDate)
51
- const hasDate = parsed !== null && !Number.isNaN(parsed.getTime())
52
- const location = stringField(entry, 'location')
70
+ function mediaLink(
71
+ entry: ContentEntry,
72
+ ctx: RenderContext,
73
+ className: string,
74
+ sizes: string,
75
+ ): HtmlElement | null {
76
+ const source = entryImage(entry, ctx)
77
+ if (source === undefined) return null
78
+ return h(
79
+ 'a',
80
+ {
81
+ class: `${className}__media`,
82
+ href: entryHref(entry, ctx),
83
+ tabindex: '-1',
84
+ 'aria-hidden': 'true',
85
+ },
86
+ renderImageSource(source, { className: `${className}__image`, sizes }),
87
+ )
88
+ }
89
+
90
+ function titleLink(
91
+ entry: ContentEntry,
92
+ ctx: RenderContext,
93
+ tag: HeadingTag,
94
+ className: string,
95
+ ): HtmlElement {
96
+ return heading(
97
+ tag,
98
+ { class: `${className}__title` },
99
+ h('a', { class: `${className}__link`, href: entryHref(entry, ctx) }, entryTitle(entry, ctx)),
100
+ )
101
+ }
102
+
103
+ function event(
104
+ entry: ContentEntry,
105
+ time: EventTime,
106
+ ctx: RenderContext,
107
+ tag: HeadingTag,
108
+ ): HtmlElement {
109
+ const hours = hoursOf(time, ctx.locale)
110
+ const place = placeOf(entry)
53
111
  const excerpt = entryExcerpt(entry)
54
- const cover = entryImage(entry, ctx, { width: 320, height: 320, fit: 'cover' })
55
-
56
- const badge = !hasDate
57
- ? null
58
- : h(
59
- 'time',
60
- { class: 'cg-event-card__date', datetime: rawDate },
61
- h('span', { class: 'cg-event-card__day' }, String((parsed as Date).getDate())),
62
- h(
63
- 'span',
64
- { class: 'cg-event-card__month' },
65
- new Intl.DateTimeFormat(ctx.locale, { month: 'short' }).format(parsed as Date),
66
- ),
67
- h(
68
- 'span',
69
- { class: 'cg-event-card__time' },
70
- new Intl.DateTimeFormat(ctx.locale, { hour: 'numeric', minute: '2-digit' }).format(
71
- parsed as Date,
112
+ const cost = textOf(entry.cost)
113
+ return h(
114
+ 'li',
115
+ { class: 'ca-events__item' },
116
+ renderDateBlock(time, ctx.locale, 'ca-date'),
117
+ h(
118
+ 'div',
119
+ { class: 'ca-events__body' },
120
+ titleLink(entry, ctx, tag, 'ca-events'),
121
+ hours === undefined && place === undefined
122
+ ? null
123
+ : h(
124
+ 'p',
125
+ { class: 'ca-events__meta' },
126
+ hours === undefined ? null : h('span', { class: 'ca-events__hours' }, hours),
127
+ place === undefined ? null : h('span', { class: 'ca-events__place' }, place),
72
128
  ),
73
- ),
74
- )
129
+ excerpt === undefined ? null : h('p', { class: 'ca-events__text' }, excerpt),
130
+ ),
131
+ cost === undefined ? null : h('p', { class: 'ca-events__cost' }, cost),
132
+ )
133
+ }
75
134
 
135
+ function row(entry: ContentEntry, ctx: RenderContext, tag: HeadingTag): HtmlElement {
136
+ const excerpt = entryExcerpt(entry)
137
+ const facts = factsOf(entry, ctx.locale)
138
+ const when = facts.find((fact) => fact.key === 'when')
139
+ const rest = facts.filter((fact) => fact.key === 'where' || fact.key === 'audience')
76
140
  return h(
77
141
  'li',
78
- { class: 'cg-event-card' },
79
- badge,
80
- cover === undefined
81
- ? null
82
- : h('div', { class: 'cg-event-card__cover' }, renderImageSource(cover, { loading: 'lazy' })),
142
+ { class: 'ca-rows__item' },
143
+ mediaLink(entry, ctx, 'ca-rows', '(min-width: 64rem) 30vw, 100vw'),
83
144
  h(
84
145
  'div',
85
- { class: 'cg-event-card__body' },
86
- location === undefined ? null : h('p', { class: 'cg-event-card__location' }, location),
87
- heading(
88
- tag,
89
- { class: 'cg-event-card__title' },
90
- h(
91
- 'a',
92
- { class: 'cg-event-card__link', href: entryHref(entry, ctx) },
93
- entryTitle(entry, ctx),
94
- ),
95
- ),
96
- excerpt === undefined ? null : h('p', { class: 'cg-event-card__excerpt' }, excerpt),
146
+ { class: 'ca-rows__body' },
147
+ when === undefined ? null : h('p', { class: 'ca-kicker ca-rows__when' }, when.value),
148
+ titleLink(entry, ctx, tag, 'ca-rows'),
149
+ excerpt === undefined ? null : h('p', { class: 'ca-rows__text' }, excerpt),
150
+ renderFacts(rest, 'ca-rows__facts'),
97
151
  ),
98
152
  )
99
153
  }
100
154
 
155
+ function photo(entry: ContentEntry, ctx: RenderContext, tag: HeadingTag): HtmlElement {
156
+ const excerpt = entryExcerpt(entry)
157
+ return h(
158
+ 'li',
159
+ { class: 'ca-photos__item' },
160
+ mediaLink(entry, ctx, 'ca-photos', '(min-width: 64rem) 26vw, 80vw'),
161
+ titleLink(entry, ctx, tag, 'ca-photos'),
162
+ excerpt === undefined ? null : h('p', { class: 'ca-photos__text' }, excerpt),
163
+ )
164
+ }
165
+
166
+ function indexItem(entry: ContentEntry, ctx: RenderContext, tag: HeadingTag): HtmlElement {
167
+ const excerpt = entryExcerpt(entry)
168
+ return h(
169
+ 'li',
170
+ { class: 'ca-index__item' },
171
+ titleLink(entry, ctx, tag, 'ca-index'),
172
+ excerpt === undefined ? null : h('p', { class: 'ca-index__text' }, excerpt),
173
+ )
174
+ }
175
+
176
+ /** The entries that are not the page being rendered. */
177
+ function othersThanThisPage(
178
+ entries: readonly ContentEntry[],
179
+ ctx: RenderContext,
180
+ ): readonly ContentEntry[] {
181
+ return entries.filter((entry) => entryHref(entry, ctx) !== ctx.url.pathname)
182
+ }
183
+
184
+ function scroller(block: CollectionListBlock, ctx: RenderContext, list: HtmlElement): HtmlElement {
185
+ return h(
186
+ 'div',
187
+ {
188
+ class: 'ca-list__viewport',
189
+ role: 'region',
190
+ 'aria-label': block.title ?? ctx.t('collection.carousel'),
191
+ tabindex: '0',
192
+ },
193
+ list,
194
+ )
195
+ }
196
+
197
+ function body(
198
+ shape: Shape,
199
+ shown: readonly ContentEntry[],
200
+ block: CollectionListBlock,
201
+ ctx: RenderContext,
202
+ tag: HeadingTag,
203
+ ): HtmlElement {
204
+ switch (shape) {
205
+ case 'events': {
206
+ const dated = shown
207
+ .map((entry) => ({ entry, time: eventTimeOf(entry) as EventTime }))
208
+ .sort((a, b) => a.time.start.date.getTime() - b.time.start.date.getTime())
209
+ const list = h(
210
+ 'ul',
211
+ { class: 'ca-list__items ca-events' },
212
+ dated.map(({ entry, time }) => event(entry, time, ctx, tag)),
213
+ )
214
+ return block.layout === 'carousel' ? scroller(block, ctx, list) : list
215
+ }
216
+ case 'rows':
217
+ return h(
218
+ 'ul',
219
+ { class: 'ca-list__items ca-rows' },
220
+ shown.map((entry) => row(entry, ctx, tag)),
221
+ )
222
+ case 'photos': {
223
+ const list = h(
224
+ 'ul',
225
+ { class: 'ca-list__items ca-photos' },
226
+ shown.map((entry) => photo(entry, ctx, tag)),
227
+ )
228
+ return block.layout === 'carousel' ? scroller(block, ctx, list) : list
229
+ }
230
+ case 'index':
231
+ return h(
232
+ 'ul',
233
+ { class: 'ca-list__items ca-index' },
234
+ shown.map((entry) => indexItem(entry, ctx, tag)),
235
+ )
236
+ }
237
+ }
238
+
101
239
  export function renderCollectionList(
102
240
  block: CollectionListBlock,
103
241
  ctx: RenderContext,
104
- entries: readonly ContentEntry[],
242
+ fetched: readonly ContentEntry[],
105
243
  ): HtmlElement {
106
- const hasTitle = block.title !== undefined
107
- const entryTag = nestedHeadingTag('collectionList', hasTitle)
108
- const items =
109
- entries.length === 0
110
- ? h('p', { class: 'cg-list__empty' }, ctx.t('collection.empty'))
111
- : h(
112
- 'ul',
113
- { class: 'cg-list__items cg-event-cards' },
114
- entries.map((entry) => renderEntry(entry, ctx, entryTag)),
115
- )
244
+ const titled = block.title !== undefined
245
+ const shown = othersThanThisPage(fetched, ctx)
246
+ const tag = nestedHeadingTag('collectionList', titled)
116
247
 
117
- return h(
248
+ if (shown.length === 0) {
249
+ return section(
250
+ 'section',
251
+ 'collectionList',
252
+ 'ca-list',
253
+ { 'data-layout': block.layout, 'data-shape': 'empty' },
254
+ 'div',
255
+ sectionHead('collectionList', block.title),
256
+ h('p', { class: 'ca-empty' }, ctx.t('collection.empty')),
257
+ )
258
+ }
259
+
260
+ const shape = shapeOf(shown, ctx, block.layout)
261
+ return section(
118
262
  'section',
119
- {
120
- class: 'cg-block cg-list',
121
- 'data-block': 'collectionList',
122
- 'data-layout': block.layout,
123
- },
124
- hasTitle
125
- ? heading(
126
- blockHeadingTag('collectionList') ?? 'h2',
127
- { class: 'cg-list__title-heading', 'data-field': 'title' },
128
- block.title ?? '',
129
- )
130
- : null,
131
- block.layout === 'carousel'
132
- ? h(
133
- 'div',
134
- {
135
- class: 'cg-list__viewport',
136
- role: 'region',
137
- 'aria-label': block.title ?? ctx.t('collection.carousel'),
138
- tabindex: '0',
139
- },
140
- items,
141
- )
142
- : items,
263
+ 'collectionList',
264
+ 'ca-list',
265
+ { 'data-layout': block.layout, 'data-shape': shape },
266
+ 'div',
267
+ sectionHead('collectionList', block.title),
268
+ body(shape, shown, block, ctx, tag),
143
269
  )
144
270
  }
271
+
272
+ /** The query this block needs, fetched by the host before any markup is built. */
273
+ export function query(block: CollectionListBlock): QueryRequest {
274
+ return buildCollectionListQuery(block)
275
+ }