@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.
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/render/blocks/accordion.d.ts.map +1 -1
- package/dist/src/render/blocks/accordion.js +13 -10
- package/dist/src/render/blocks/accordion.js.map +1 -1
- package/dist/src/render/blocks/breakdown.d.ts +14 -0
- package/dist/src/render/blocks/breakdown.d.ts.map +1 -0
- package/dist/src/render/blocks/breakdown.js +17 -0
- package/dist/src/render/blocks/breakdown.js.map +1 -0
- package/dist/src/render/blocks/collection-list.d.ts +4 -10
- package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
- package/dist/src/render/blocks/collection-list.js +89 -58
- package/dist/src/render/blocks/collection-list.js.map +1 -1
- package/dist/src/render/blocks/cta.d.ts +0 -5
- package/dist/src/render/blocks/cta.d.ts.map +1 -1
- package/dist/src/render/blocks/cta.js +22 -10
- package/dist/src/render/blocks/cta.js.map +1 -1
- package/dist/src/render/blocks/embed.d.ts.map +1 -1
- package/dist/src/render/blocks/embed.js +30 -22
- package/dist/src/render/blocks/embed.js.map +1 -1
- package/dist/src/render/blocks/faq.d.ts.map +1 -1
- package/dist/src/render/blocks/faq.js +11 -15
- package/dist/src/render/blocks/faq.js.map +1 -1
- package/dist/src/render/blocks/feature-grid.d.ts +6 -0
- package/dist/src/render/blocks/feature-grid.d.ts.map +1 -1
- package/dist/src/render/blocks/feature-grid.js +42 -20
- package/dist/src/render/blocks/feature-grid.js.map +1 -1
- package/dist/src/render/blocks/gallery.d.ts +9 -7
- package/dist/src/render/blocks/gallery.d.ts.map +1 -1
- package/dist/src/render/blocks/gallery.js +22 -16
- package/dist/src/render/blocks/gallery.js.map +1 -1
- package/dist/src/render/blocks/hero.d.ts +23 -9
- package/dist/src/render/blocks/hero.d.ts.map +1 -1
- package/dist/src/render/blocks/hero.js +40 -23
- package/dist/src/render/blocks/hero.js.map +1 -1
- package/dist/src/render/blocks/logo-strip.d.ts +6 -0
- package/dist/src/render/blocks/logo-strip.d.ts.map +1 -1
- package/dist/src/render/blocks/logo-strip.js +7 -9
- package/dist/src/render/blocks/logo-strip.js.map +1 -1
- package/dist/src/render/blocks/logos.d.ts +14 -0
- package/dist/src/render/blocks/logos.d.ts.map +1 -1
- package/dist/src/render/blocks/logos.js +30 -16
- package/dist/src/render/blocks/logos.js.map +1 -1
- package/dist/src/render/blocks/media-figure.d.ts +12 -5
- package/dist/src/render/blocks/media-figure.d.ts.map +1 -1
- package/dist/src/render/blocks/media-figure.js +32 -18
- package/dist/src/render/blocks/media-figure.js.map +1 -1
- package/dist/src/render/blocks/pricing-table.d.ts.map +1 -1
- package/dist/src/render/blocks/pricing-table.js +18 -20
- package/dist/src/render/blocks/pricing-table.js.map +1 -1
- package/dist/src/render/blocks/prose.d.ts +9 -3
- package/dist/src/render/blocks/prose.d.ts.map +1 -1
- package/dist/src/render/blocks/prose.js +11 -4
- package/dist/src/render/blocks/prose.js.map +1 -1
- package/dist/src/render/blocks/quote.d.ts +4 -7
- package/dist/src/render/blocks/quote.d.ts.map +1 -1
- package/dist/src/render/blocks/quote.js +12 -17
- package/dist/src/render/blocks/quote.js.map +1 -1
- package/dist/src/render/blocks/stat-counter.d.ts +8 -1
- package/dist/src/render/blocks/stat-counter.d.ts.map +1 -1
- package/dist/src/render/blocks/stat-counter.js +18 -10
- package/dist/src/render/blocks/stat-counter.js.map +1 -1
- package/dist/src/render/blocks/stats.d.ts +12 -1
- package/dist/src/render/blocks/stats.d.ts.map +1 -1
- package/dist/src/render/blocks/stats.js +24 -14
- package/dist/src/render/blocks/stats.js.map +1 -1
- package/dist/src/render/blocks/testimonial.d.ts +6 -5
- package/dist/src/render/blocks/testimonial.d.ts.map +1 -1
- package/dist/src/render/blocks/testimonial.js +13 -11
- package/dist/src/render/blocks/testimonial.js.map +1 -1
- package/dist/src/render/chrome.d.ts +38 -1
- package/dist/src/render/chrome.d.ts.map +1 -1
- package/dist/src/render/chrome.js +117 -91
- package/dist/src/render/chrome.js.map +1 -1
- package/dist/src/render/details.d.ts +79 -0
- package/dist/src/render/details.d.ts.map +1 -0
- package/dist/src/render/details.js +221 -0
- package/dist/src/render/details.js.map +1 -0
- package/dist/src/render/figures.d.ts +29 -0
- package/dist/src/render/figures.d.ts.map +1 -0
- package/dist/src/render/figures.js +59 -0
- package/dist/src/render/figures.js.map +1 -0
- package/dist/src/render/layout.d.ts +31 -0
- package/dist/src/render/layout.d.ts.map +1 -0
- package/dist/src/render/layout.js +46 -0
- package/dist/src/render/layout.js.map +1 -0
- package/dist/src/render/page-head.d.ts +7 -0
- package/dist/src/render/page-head.d.ts.map +1 -0
- package/dist/src/render/page-head.js +95 -0
- package/dist/src/render/page-head.js.map +1 -0
- package/dist/src/render/render-block.d.ts +8 -12
- package/dist/src/render/render-block.d.ts.map +1 -1
- package/dist/src/render/render-block.js +40 -29
- package/dist/src/render/render-block.js.map +1 -1
- package/dist/src/render/strings.d.ts +15 -0
- package/dist/src/render/strings.d.ts.map +1 -0
- package/dist/src/render/strings.js +39 -0
- package/dist/src/render/strings.js.map +1 -0
- package/dist/src/render/term-archive.d.ts.map +1 -1
- package/dist/src/render/term-archive.js +33 -25
- package/dist/src/render/term-archive.js.map +1 -1
- package/dist/src/render/widget-areas.d.ts +14 -0
- package/dist/src/render/widget-areas.d.ts.map +1 -0
- package/dist/src/render/widget-areas.js +21 -0
- package/dist/src/render/widget-areas.js.map +1 -0
- package/dist/theme.config.d.ts +1 -1
- package/dist/theme.config.js +3 -3
- package/dist/theme.config.js.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +9 -0
- package/src/render/blocks/accordion.ts +28 -22
- package/src/render/blocks/breakdown.ts +42 -0
- package/src/render/blocks/collection-list.ts +234 -103
- package/src/render/blocks/cta.ts +48 -19
- package/src/render/blocks/embed.ts +47 -29
- package/src/render/blocks/faq.ts +22 -31
- package/src/render/blocks/feature-grid.ts +73 -41
- package/src/render/blocks/gallery.ts +32 -26
- package/src/render/blocks/hero.ts +56 -43
- package/src/render/blocks/logo-strip.ts +23 -21
- package/src/render/blocks/logos.ts +45 -40
- package/src/render/blocks/media-figure.ts +49 -24
- package/src/render/blocks/pricing-table.ts +31 -40
- package/src/render/blocks/prose.ts +16 -6
- package/src/render/blocks/quote.ts +34 -27
- package/src/render/blocks/stat-counter.ts +35 -29
- package/src/render/blocks/stats.ts +46 -38
- package/src/render/blocks/testimonial.ts +29 -20
- package/src/render/chrome.ts +165 -91
- package/src/render/details.ts +276 -0
- package/src/render/figures.ts +68 -0
- package/src/render/layout.ts +78 -0
- package/src/render/page-head.ts +193 -0
- package/src/render/render-block.ts +45 -32
- package/src/render/strings.ts +74 -0
- package/src/render/term-archive.ts +94 -58
- package/src/render/widget-areas.ts +24 -0
- package/src/styles/archive.css +38 -102
- package/src/styles/base.css +503 -554
- package/src/styles/blocks.css +913 -666
- package/src/styles/chrome.css +506 -0
- package/src/styles/listings.css +591 -0
- package/src/styles/theme.css +25 -19
- package/src/styles/tokens.css +284 -234
- package/src/styles/widgets.css +1059 -0
- package/tokens.json +18 -18
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
import type { LogoStripBlock
|
|
1
|
+
import type { LogoStripBlock } from '@cogenta/blocks'
|
|
2
2
|
import { type HtmlElement, h, image, type RenderContext } from '@cogenta/theme-kit'
|
|
3
|
+
import { section } from '../layout.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* The lighter row of marks: the caption at the caption size above a rule,
|
|
7
|
+
* and the marks spread along one line under it, small and evenly spaced, in
|
|
8
|
+
* one ink. No links, by contract B; each mark is named by its own alt text
|
|
9
|
+
* from the media library.
|
|
9
10
|
*/
|
|
10
|
-
function renderItem(item: LogoStripItem, ctx: RenderContext): HtmlElement {
|
|
11
|
-
return h(
|
|
12
|
-
'li',
|
|
13
|
-
{ class: 'cg-logo-band__item' },
|
|
14
|
-
image(ctx, item.media, { className: 'cg-logo-band__image', variant: { fit: 'contain' } }),
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
11
|
export function renderLogoStrip(block: LogoStripBlock, ctx: RenderContext): HtmlElement {
|
|
19
|
-
return
|
|
20
|
-
'
|
|
21
|
-
|
|
12
|
+
return section(
|
|
13
|
+
'div',
|
|
14
|
+
'logoStrip',
|
|
15
|
+
'ca-strip',
|
|
16
|
+
{ 'data-captioned': String(block.caption !== undefined) },
|
|
17
|
+
'div',
|
|
18
|
+
block.caption === undefined
|
|
19
|
+
? null
|
|
20
|
+
: h('p', { class: 'ca-strip__caption', 'data-field': 'caption' }, block.caption),
|
|
22
21
|
h(
|
|
23
22
|
'ul',
|
|
24
|
-
{ class: '
|
|
25
|
-
block.logos.map((
|
|
23
|
+
{ class: 'ca-strip__items' },
|
|
24
|
+
block.logos.map((logo) =>
|
|
25
|
+
h(
|
|
26
|
+
'li',
|
|
27
|
+
{ class: 'ca-strip__item' },
|
|
28
|
+
image(ctx, logo.media, { className: 'ca-mark', sizes: '12rem' }),
|
|
29
|
+
),
|
|
30
|
+
),
|
|
26
31
|
),
|
|
27
|
-
block.caption === undefined
|
|
28
|
-
? null
|
|
29
|
-
: h('figcaption', { class: 'cg-logo-band__caption', 'data-field': 'caption' }, block.caption),
|
|
30
32
|
)
|
|
31
33
|
}
|
|
@@ -1,52 +1,57 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type HtmlElement,
|
|
5
|
-
h,
|
|
6
|
-
heading,
|
|
7
|
-
image,
|
|
8
|
-
type RenderContext,
|
|
9
|
-
} from '@cogenta/theme-kit'
|
|
1
|
+
import type { LogosBlock } from '@cogenta/blocks'
|
|
2
|
+
import { type HtmlElement, h, image, type RenderContext } from '@cogenta/theme-kit'
|
|
3
|
+
import { section, sectionHead } from '../layout.js'
|
|
10
4
|
|
|
11
5
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
6
|
+
* The organisations that work alongside this one: the title on the first
|
|
7
|
+
* four columns, and their marks on the last eight in a grid of cells divided
|
|
8
|
+
* by hairlines, each mark set small and in one ink so no partner shouts
|
|
9
|
+
* louder than another. A mark drawn in ink is inverted in the dark scheme.
|
|
10
|
+
*
|
|
11
|
+
* The organisation's name is the mark's accessible name when the media
|
|
12
|
+
* library has no alt text for it, and the link's own name when it links out.
|
|
15
13
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return
|
|
23
|
-
'li',
|
|
24
|
-
{ class: 'cg-logo' },
|
|
25
|
-
item.url === undefined
|
|
26
|
-
? logo
|
|
27
|
-
: h(
|
|
28
|
-
'a',
|
|
29
|
-
{ class: 'cg-logo__link', href: ctx.link(item.url), rel: 'noopener noreferrer' },
|
|
30
|
-
logo,
|
|
31
|
-
),
|
|
32
|
-
)
|
|
14
|
+
/**
|
|
15
|
+
* Columns on a wide screen that leave no empty cell in the grid: three when
|
|
16
|
+
* the count divides by three, two when it divides by two, otherwise three.
|
|
17
|
+
*/
|
|
18
|
+
export function logoColumnsFor(count: number): number {
|
|
19
|
+
if (count % 3 === 0) return 3
|
|
20
|
+
return count % 2 === 0 ? 2 : 3
|
|
33
21
|
}
|
|
34
22
|
|
|
35
23
|
export function renderLogos(block: LogosBlock, ctx: RenderContext): HtmlElement {
|
|
36
|
-
return
|
|
24
|
+
return section(
|
|
37
25
|
'section',
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
'logos',
|
|
27
|
+
'ca-partners',
|
|
28
|
+
{
|
|
29
|
+
'data-titled': String(block.title !== undefined),
|
|
30
|
+
'data-columns': String(logoColumnsFor(block.items.length)),
|
|
31
|
+
},
|
|
32
|
+
'div',
|
|
33
|
+
sectionHead('logos', block.title),
|
|
46
34
|
h(
|
|
47
35
|
'ul',
|
|
48
|
-
{ class: '
|
|
49
|
-
block.items.map((item) =>
|
|
36
|
+
{ class: 'ca-partners__items' },
|
|
37
|
+
block.items.map((item) => {
|
|
38
|
+
const mark = image(ctx, item.media, {
|
|
39
|
+
className: 'ca-mark',
|
|
40
|
+
altFrom: item.name,
|
|
41
|
+
sizes: '12rem',
|
|
42
|
+
})
|
|
43
|
+
return h(
|
|
44
|
+
'li',
|
|
45
|
+
{ class: 'ca-partners__item' },
|
|
46
|
+
item.url === undefined
|
|
47
|
+
? h('span', { class: 'ca-partners__cell' }, mark)
|
|
48
|
+
: h(
|
|
49
|
+
'a',
|
|
50
|
+
{ class: 'ca-partners__cell', href: item.url, rel: 'noopener noreferrer' },
|
|
51
|
+
mark,
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
}),
|
|
50
55
|
),
|
|
51
56
|
)
|
|
52
57
|
}
|
|
@@ -1,38 +1,63 @@
|
|
|
1
1
|
import type { MediaFigureBlock } from '@cogenta/blocks'
|
|
2
2
|
import { aspectRatio, type HtmlElement, h, image, type RenderContext } from '@cogenta/theme-kit'
|
|
3
|
+
import { section } from '../layout.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* A photograph and its caption, the caption always under the picture's own
|
|
7
|
+
* left edge, in the text face, with the credit after it.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* `align` is an editorial intent, read as a layout:
|
|
10
|
+
*
|
|
11
|
+
* - `start` / `end`: seven columns on that side, the caption beside it on the
|
|
12
|
+
* other four, set against the bottom of the picture.
|
|
13
|
+
* - `center`: eight columns, set in from the second.
|
|
14
|
+
* - `wide` (and no value): the whole container.
|
|
15
|
+
* - `full`: the whole window, edge to edge.
|
|
16
|
+
*
|
|
17
|
+
* The ratio crops from the middle, or from the media's own focal point; the
|
|
18
|
+
* corners stay square and the picture casts no shadow.
|
|
11
19
|
*/
|
|
12
20
|
export function renderMediaFigure(block: MediaFigureBlock, ctx: RenderContext): HtmlElement {
|
|
21
|
+
const align = block.align ?? 'wide'
|
|
22
|
+
const split = align === 'start' || align === 'end'
|
|
13
23
|
const ratio = aspectRatio(block.ratio)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'data-block': 'mediaFigure',
|
|
20
|
-
'data-align': block.align ?? 'center',
|
|
21
|
-
style: ratio === undefined ? undefined : `--cg-ratio:${ratio}`,
|
|
22
|
-
},
|
|
23
|
-
image(ctx, block.media, {
|
|
24
|
-
className: 'cg-figure__media',
|
|
25
|
-
sizes: '(min-width: 45rem) 40rem, 100vw',
|
|
26
|
-
}),
|
|
27
|
-
hasCaption
|
|
28
|
-
? h(
|
|
24
|
+
|
|
25
|
+
const caption =
|
|
26
|
+
block.caption === undefined && block.credit === undefined
|
|
27
|
+
? null
|
|
28
|
+
: h(
|
|
29
29
|
'figcaption',
|
|
30
|
-
{ class: '
|
|
31
|
-
block.caption
|
|
30
|
+
{ class: 'ca-figure__caption' },
|
|
31
|
+
block.caption === undefined
|
|
32
|
+
? null
|
|
33
|
+
: h('span', { class: 'ca-figure__text', 'data-field': 'caption' }, block.caption),
|
|
32
34
|
block.credit === undefined
|
|
33
35
|
? null
|
|
34
|
-
: h('span', { class: '
|
|
36
|
+
: h('span', { class: 'ca-figure__credit', 'data-field': 'credit' }, block.credit),
|
|
35
37
|
)
|
|
36
|
-
|
|
38
|
+
|
|
39
|
+
return section(
|
|
40
|
+
'div',
|
|
41
|
+
'mediaFigure',
|
|
42
|
+
'ca-figure',
|
|
43
|
+
{ 'data-align': align, 'data-layout': split ? 'split' : 'single' },
|
|
44
|
+
'figure',
|
|
45
|
+
h(
|
|
46
|
+
'div',
|
|
47
|
+
{
|
|
48
|
+
class: 'ca-figure__frame',
|
|
49
|
+
style: ratio === undefined ? undefined : `aspect-ratio:${ratio}`,
|
|
50
|
+
},
|
|
51
|
+
image(ctx, block.media, {
|
|
52
|
+
className: 'ca-figure__image',
|
|
53
|
+
sizes:
|
|
54
|
+
align === 'full'
|
|
55
|
+
? '100vw'
|
|
56
|
+
: split
|
|
57
|
+
? '(min-width: 64rem) 55vw, 100vw'
|
|
58
|
+
: '(min-width: 82rem) 78rem, 100vw',
|
|
59
|
+
}),
|
|
60
|
+
),
|
|
61
|
+
caption,
|
|
37
62
|
)
|
|
38
63
|
}
|
|
@@ -1,73 +1,64 @@
|
|
|
1
1
|
import type { PricingTableBlock, PricingTier } from '@cogenta/blocks'
|
|
2
2
|
import {
|
|
3
3
|
actionLink,
|
|
4
|
-
blockHeadingTag,
|
|
5
|
-
type HeadingTag,
|
|
6
4
|
type HtmlElement,
|
|
7
5
|
h,
|
|
8
6
|
heading,
|
|
9
7
|
nestedHeadingTag,
|
|
10
8
|
type RenderContext,
|
|
11
9
|
} from '@cogenta/theme-kit'
|
|
10
|
+
import { section, sectionHead } from '../layout.js'
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
13
|
+
* Levels side by side: a membership, a regular gift, a sponsored place.
|
|
14
|
+
* Ruled columns rather than cards: the name of the level, the amount large in
|
|
15
|
+
* the display face with tabular figures and what it covers ("a month") beside
|
|
16
|
+
* it, then what it includes one line at a time between hairlines, and the
|
|
17
|
+
* action at the foot.
|
|
18
|
+
*
|
|
19
|
+
* `highlighted` is an editorial emphasis, drawn as the column's top rule in
|
|
20
|
+
* the organisation's green, thicker, and its name in the same green. No
|
|
21
|
+
* ribbon, no raised card, no fill.
|
|
19
22
|
*/
|
|
20
|
-
function
|
|
23
|
+
function tier(item: PricingTier, ctx: RenderContext, titled: boolean): HtmlElement {
|
|
21
24
|
return h(
|
|
22
25
|
'li',
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
'data-highlighted': tier.highlighted === true ? 'true' : undefined,
|
|
26
|
-
'aria-current': tier.highlighted === true ? 'true' : undefined,
|
|
27
|
-
},
|
|
28
|
-
heading(tag, { class: 'cg-pricing__name' }, tier.name),
|
|
26
|
+
{ class: 'ca-levels__tier', 'data-highlighted': item.highlighted === true ? 'true' : 'false' },
|
|
27
|
+
heading(nestedHeadingTag('pricingTable', titled), { class: 'ca-levels__name' }, item.name),
|
|
29
28
|
h(
|
|
30
29
|
'p',
|
|
31
|
-
{ class: '
|
|
32
|
-
h('span', { class: '
|
|
33
|
-
|
|
30
|
+
{ class: 'ca-levels__price' },
|
|
31
|
+
h('span', { class: 'ca-levels__amount' }, item.price),
|
|
32
|
+
item.interval === undefined
|
|
34
33
|
? null
|
|
35
|
-
: h('span', { class: '
|
|
34
|
+
: h('span', { class: 'ca-levels__interval' }, item.interval),
|
|
36
35
|
),
|
|
37
|
-
|
|
36
|
+
item.features.length === 0
|
|
38
37
|
? null
|
|
39
38
|
: h(
|
|
40
39
|
'ul',
|
|
41
|
-
{ class: '
|
|
42
|
-
|
|
40
|
+
{ class: 'ca-levels__lines' },
|
|
41
|
+
item.features.map((feature) => h('li', { class: 'ca-levels__line' }, feature)),
|
|
43
42
|
),
|
|
44
|
-
|
|
43
|
+
item.action === undefined
|
|
45
44
|
? null
|
|
46
|
-
: h(
|
|
47
|
-
'div',
|
|
48
|
-
{ class: 'cg-pricing__action' },
|
|
49
|
-
actionLink(ctx, { ...tier.action, emphasis: tier.action.emphasis ?? 'primary' }),
|
|
50
|
-
),
|
|
45
|
+
: h('div', { class: 'ca-levels__action' }, actionLink(ctx, item.action)),
|
|
51
46
|
)
|
|
52
47
|
}
|
|
53
48
|
|
|
54
49
|
export function renderPricingTable(block: PricingTableBlock, ctx: RenderContext): HtmlElement {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
return h(
|
|
50
|
+
const titled = block.title !== undefined
|
|
51
|
+
return section(
|
|
58
52
|
'section',
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
block.title ?? '',
|
|
65
|
-
)
|
|
66
|
-
: null,
|
|
53
|
+
'pricingTable',
|
|
54
|
+
'ca-levels',
|
|
55
|
+
{ 'data-count': String(Math.min(block.tiers.length, 4)) },
|
|
56
|
+
'div',
|
|
57
|
+
sectionHead('pricingTable', block.title),
|
|
67
58
|
h(
|
|
68
59
|
'ul',
|
|
69
|
-
{ class: '
|
|
70
|
-
block.tiers.map((
|
|
60
|
+
{ class: 'ca-levels__tiers' },
|
|
61
|
+
block.tiers.map((item) => tier(item, ctx, titled)),
|
|
71
62
|
),
|
|
72
63
|
)
|
|
73
64
|
}
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import type { ProseBlock } from '@cogenta/blocks'
|
|
2
2
|
import { type HtmlElement, h, type RenderContext, renderRichText } from '@cogenta/theme-kit'
|
|
3
|
+
import { section } from '../layout.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Running text: the organisation's history, how to give, how volunteering
|
|
7
|
+
* works, a privacy notice.
|
|
8
|
+
*
|
|
9
|
+
* `prose` declares `headingLevel: 'none'`, so it adds no heading of its own;
|
|
10
|
+
* the rich text's own headings start at `h2`. The column starts on the first
|
|
11
|
+
* of twelve columns, on the same edge as the page title above it, and holds a
|
|
12
|
+
* reading measure of about sixty-six characters. The first paragraph of the
|
|
13
|
+
* first text under a page title is set a step larger, the way a report opens
|
|
14
|
+
* with its summary.
|
|
8
15
|
*/
|
|
9
16
|
export function renderProse(block: ProseBlock, ctx: RenderContext): HtmlElement {
|
|
10
|
-
return
|
|
17
|
+
return section(
|
|
11
18
|
'div',
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
'prose',
|
|
20
|
+
'ca-prose',
|
|
21
|
+
{},
|
|
22
|
+
'div',
|
|
23
|
+
h('div', { class: 'ca-prose__body' }, renderRichText(ctx, block.body)),
|
|
14
24
|
)
|
|
15
25
|
}
|
|
@@ -1,39 +1,46 @@
|
|
|
1
1
|
import type { QuoteBlock } from '@cogenta/blocks'
|
|
2
2
|
import { type HtmlElement, h, image, type RenderContext } from '@cogenta/theme-kit'
|
|
3
|
+
import { section } from '../layout.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* The avatar is decorative here — the name is right beside it in text — so
|
|
10
|
-
* its media entity's alt text is expected to be empty. `image` still writes
|
|
11
|
-
* the attribute either way.
|
|
6
|
+
* A few words someone said, set large: the text in the display face across
|
|
7
|
+
* nine columns, with a real opening quotation mark hung in the margin by the
|
|
8
|
+
* stylesheet, and the speaker's name and role small beneath it. A portrait,
|
|
9
|
+
* when there is one, is a small square crop beside the name.
|
|
12
10
|
*/
|
|
13
11
|
export function renderQuote(block: QuoteBlock, ctx: RenderContext): HtmlElement {
|
|
14
|
-
const
|
|
15
|
-
block.author
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{ class: 'cg-block cg-quote', 'data-block': 'quote' },
|
|
19
|
-
h('blockquote', { class: 'cg-quote__text' }, h('p', { 'data-field': 'text' }, block.text)),
|
|
20
|
-
hasAttribution
|
|
21
|
-
? h(
|
|
12
|
+
const who =
|
|
13
|
+
block.author === undefined && block.role === undefined
|
|
14
|
+
? null
|
|
15
|
+
: h(
|
|
22
16
|
'figcaption',
|
|
23
|
-
{ class: '
|
|
17
|
+
{ class: 'ca-quote__attribution' },
|
|
24
18
|
block.avatar === undefined
|
|
25
19
|
? null
|
|
26
|
-
: image(ctx, block.avatar, {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
: image(ctx, block.avatar, { className: 'ca-quote__avatar', sizes: '3.5rem' }),
|
|
21
|
+
h(
|
|
22
|
+
'span',
|
|
23
|
+
{ class: 'ca-quote__who' },
|
|
24
|
+
block.author === undefined
|
|
25
|
+
? null
|
|
26
|
+
: h('span', { class: 'ca-quote__author', 'data-field': 'author' }, block.author),
|
|
27
|
+
block.role === undefined
|
|
28
|
+
? null
|
|
29
|
+
: h('span', { class: 'ca-quote__role', 'data-field': 'role' }, block.role),
|
|
30
|
+
),
|
|
36
31
|
)
|
|
37
|
-
|
|
32
|
+
|
|
33
|
+
return section(
|
|
34
|
+
'div',
|
|
35
|
+
'quote',
|
|
36
|
+
'ca-quote',
|
|
37
|
+
{},
|
|
38
|
+
'figure',
|
|
39
|
+
h(
|
|
40
|
+
'blockquote',
|
|
41
|
+
{ class: 'ca-quote__quote' },
|
|
42
|
+
h('p', { class: 'ca-quote__text', 'data-field': 'text' }, block.text),
|
|
43
|
+
),
|
|
44
|
+
who,
|
|
38
45
|
)
|
|
39
46
|
}
|
|
@@ -1,36 +1,42 @@
|
|
|
1
|
-
import type { StatCounterBlock
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
heading,
|
|
7
|
-
type RenderContext,
|
|
8
|
-
} from '@cogenta/theme-kit'
|
|
1
|
+
import type { StatCounterBlock } from '@cogenta/blocks'
|
|
2
|
+
import { type HtmlElement, h, type RenderContext } from '@cogenta/theme-kit'
|
|
3
|
+
import { isBreakdown } from '../figures.js'
|
|
4
|
+
import { section, sectionHead } from '../layout.js'
|
|
5
|
+
import { renderBreakdown } from './breakdown.js'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
8
|
+
* The narrower sibling of `stats` (a value and a short label, no unit): a
|
|
9
|
+
* single row of figures across the container, divided by vertical hairlines,
|
|
10
|
+
* each number in the display face over its label. Percentages of one whole
|
|
11
|
+
* are drawn as a breakdown, the same as `stats`. Nothing counts up; a number
|
|
12
|
+
* that animates into place is a number a visitor has to wait for.
|
|
13
13
|
*/
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{ class: 'cg-stat-counter' },
|
|
18
|
-
h('dt', { class: 'cg-stat-counter__label' }, item.label),
|
|
19
|
-
h('dd', { class: 'cg-stat-counter__value' }, item.value),
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function renderStatCounter(block: StatCounterBlock, _ctx: RenderContext): HtmlElement {
|
|
24
|
-
return h(
|
|
14
|
+
export function renderStatCounter(block: StatCounterBlock, ctx: RenderContext): HtmlElement {
|
|
15
|
+
const breakdown = isBreakdown(block.stats)
|
|
16
|
+
return section(
|
|
25
17
|
'section',
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
'statCounter',
|
|
19
|
+
'ca-counter',
|
|
20
|
+
{
|
|
21
|
+
'data-shape': breakdown ? 'breakdown' : 'row',
|
|
22
|
+
'data-count': String(Math.min(block.stats.length, 4)),
|
|
23
|
+
'data-titled': String(block.title !== undefined),
|
|
24
|
+
},
|
|
25
|
+
'div',
|
|
26
|
+
sectionHead('statCounter', block.title),
|
|
27
|
+
breakdown
|
|
28
|
+
? renderBreakdown(block.stats, ctx)
|
|
29
|
+
: h(
|
|
30
|
+
'dl',
|
|
31
|
+
{ class: 'ca-counter__items' },
|
|
32
|
+
block.stats.map((stat) =>
|
|
33
|
+
h(
|
|
34
|
+
'div',
|
|
35
|
+
{ class: 'ca-counter__item' },
|
|
36
|
+
h('dt', { class: 'ca-counter__label' }, stat.label),
|
|
37
|
+
h('dd', { class: 'ca-counter__value' }, stat.value),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
33
40
|
),
|
|
34
|
-
h('dl', { class: 'cg-stat-counters__items' }, block.stats.map(renderItem)),
|
|
35
41
|
)
|
|
36
42
|
}
|
|
@@ -1,45 +1,53 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
heading,
|
|
7
|
-
type RenderContext,
|
|
8
|
-
} from '@cogenta/theme-kit'
|
|
1
|
+
import type { StatsBlock } from '@cogenta/blocks'
|
|
2
|
+
import { type HtmlElement, h, type RenderContext } from '@cogenta/theme-kit'
|
|
3
|
+
import { isBreakdown } from '../figures.js'
|
|
4
|
+
import { section, sectionHead } from '../layout.js'
|
|
5
|
+
import { renderBreakdown } from './breakdown.js'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* the
|
|
8
|
+
* What a year of work added up to, with the sentence that makes each number
|
|
9
|
+
* mean something: the title on the first four columns, and the figures on the
|
|
10
|
+
* last eight in two columns, each under a rule. The number in the display
|
|
11
|
+
* face, narrow and large, in the organisation's green with lining tabular
|
|
12
|
+
* figures and its unit a step smaller; under it the sentence of context in
|
|
13
|
+
* the text face. No box, no tint, nothing counts up.
|
|
14
|
+
*
|
|
15
|
+
* Figures that are all percentages of one whole are drawn as a breakdown
|
|
16
|
+
* instead (`renderBreakdown`).
|
|
17
17
|
*/
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
{ class: 'cg-impact-stat' },
|
|
22
|
-
h('dt', { class: 'cg-impact-stat__label' }, item.label),
|
|
23
|
-
h(
|
|
24
|
-
'dd',
|
|
25
|
-
{ class: 'cg-impact-stat__value' },
|
|
26
|
-
item.value,
|
|
27
|
-
item.unit === undefined ? null : h('span', { class: 'cg-impact-stat__unit' }, item.unit),
|
|
28
|
-
),
|
|
29
|
-
)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function renderStats(block: StatsBlock, _ctx: RenderContext): HtmlElement {
|
|
33
|
-
return h(
|
|
18
|
+
export function renderStats(block: StatsBlock, ctx: RenderContext): HtmlElement {
|
|
19
|
+
const breakdown = isBreakdown(block.items)
|
|
20
|
+
return section(
|
|
34
21
|
'section',
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
22
|
+
'stats',
|
|
23
|
+
'ca-figures',
|
|
24
|
+
{
|
|
25
|
+
'data-shape': breakdown ? 'breakdown' : 'figures',
|
|
26
|
+
'data-count': String(Math.min(block.items.length, 4)),
|
|
27
|
+
'data-titled': String(block.title !== undefined),
|
|
28
|
+
},
|
|
29
|
+
'div',
|
|
30
|
+
sectionHead('stats', block.title),
|
|
31
|
+
breakdown
|
|
32
|
+
? renderBreakdown(block.items, ctx)
|
|
33
|
+
: h(
|
|
34
|
+
'dl',
|
|
35
|
+
{ class: 'ca-figures__items' },
|
|
36
|
+
block.items.map((item) =>
|
|
37
|
+
h(
|
|
38
|
+
'div',
|
|
39
|
+
{ class: 'ca-figures__item' },
|
|
40
|
+
h('dt', { class: 'ca-figures__label' }, item.label),
|
|
41
|
+
h(
|
|
42
|
+
'dd',
|
|
43
|
+
{ class: 'ca-figures__value' },
|
|
44
|
+
item.value,
|
|
45
|
+
item.unit === undefined
|
|
46
|
+
? null
|
|
47
|
+
: h('span', { class: 'ca-figures__unit' }, item.unit),
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
),
|
|
42
51
|
),
|
|
43
|
-
h('dl', { class: 'cg-impact__items' }, block.items.map(renderItem)),
|
|
44
52
|
)
|
|
45
53
|
}
|