@cogenta/theme-portfolio 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +20 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/render/blocks/accordion.d.ts +4 -0
- package/dist/src/render/blocks/accordion.d.ts.map +1 -0
- package/dist/src/render/blocks/accordion.js +24 -0
- package/dist/src/render/blocks/accordion.js.map +1 -0
- package/dist/src/render/blocks/collection-list.d.ts +25 -0
- package/dist/src/render/blocks/collection-list.d.ts.map +1 -0
- package/dist/src/render/blocks/collection-list.js +77 -0
- package/dist/src/render/blocks/collection-list.js.map +1 -0
- package/dist/src/render/blocks/cta.d.ts +10 -0
- package/dist/src/render/blocks/cta.d.ts.map +1 -0
- package/dist/src/render/blocks/cta.js +16 -0
- package/dist/src/render/blocks/cta.js.map +1 -0
- package/dist/src/render/blocks/embed.d.ts +4 -0
- package/dist/src/render/blocks/embed.d.ts.map +1 -0
- package/dist/src/render/blocks/embed.js +88 -0
- package/dist/src/render/blocks/embed.js.map +1 -0
- package/dist/src/render/blocks/faq.d.ts +4 -0
- package/dist/src/render/blocks/faq.d.ts.map +1 -0
- package/dist/src/render/blocks/faq.js +23 -0
- package/dist/src/render/blocks/faq.js.map +1 -0
- package/dist/src/render/blocks/feature-grid.d.ts +4 -0
- package/dist/src/render/blocks/feature-grid.d.ts.map +1 -0
- package/dist/src/render/blocks/feature-grid.js +30 -0
- package/dist/src/render/blocks/feature-grid.js.map +1 -0
- package/dist/src/render/blocks/gallery.d.ts +18 -0
- package/dist/src/render/blocks/gallery.d.ts.map +1 -0
- package/dist/src/render/blocks/gallery.js +34 -0
- package/dist/src/render/blocks/gallery.js.map +1 -0
- package/dist/src/render/blocks/hero.d.ts +15 -0
- package/dist/src/render/blocks/hero.d.ts.map +1 -0
- package/dist/src/render/blocks/hero.js +31 -0
- package/dist/src/render/blocks/hero.js.map +1 -0
- package/dist/src/render/blocks/logo-strip.d.ts +4 -0
- package/dist/src/render/blocks/logo-strip.d.ts.map +1 -0
- package/dist/src/render/blocks/logo-strip.js +23 -0
- package/dist/src/render/blocks/logo-strip.js.map +1 -0
- package/dist/src/render/blocks/logos.d.ts +4 -0
- package/dist/src/render/blocks/logos.d.ts.map +1 -0
- package/dist/src/render/blocks/logos.js +28 -0
- package/dist/src/render/blocks/logos.js.map +1 -0
- package/dist/src/render/blocks/media-figure.d.ts +19 -0
- package/dist/src/render/blocks/media-figure.d.ts.map +1 -0
- package/dist/src/render/blocks/media-figure.js +36 -0
- package/dist/src/render/blocks/media-figure.js.map +1 -0
- package/dist/src/render/blocks/pricing-table.d.ts +4 -0
- package/dist/src/render/blocks/pricing-table.d.ts.map +1 -0
- package/dist/src/render/blocks/pricing-table.js +29 -0
- package/dist/src/render/blocks/pricing-table.js.map +1 -0
- package/dist/src/render/blocks/prose.d.ts +16 -0
- package/dist/src/render/blocks/prose.d.ts.map +1 -0
- package/dist/src/render/blocks/prose.js +17 -0
- package/dist/src/render/blocks/prose.js.map +1 -0
- package/dist/src/render/blocks/quote.d.ts +18 -0
- package/dist/src/render/blocks/quote.d.ts.map +1 -0
- package/dist/src/render/blocks/quote.js +31 -0
- package/dist/src/render/blocks/quote.js.map +1 -0
- package/dist/src/render/blocks/stat-counter.d.ts +4 -0
- package/dist/src/render/blocks/stat-counter.d.ts.map +1 -0
- package/dist/src/render/blocks/stat-counter.js +18 -0
- package/dist/src/render/blocks/stat-counter.js.map +1 -0
- package/dist/src/render/blocks/stats.d.ts +4 -0
- package/dist/src/render/blocks/stats.d.ts.map +1 -0
- package/dist/src/render/blocks/stats.js +22 -0
- package/dist/src/render/blocks/stats.js.map +1 -0
- package/dist/src/render/blocks/testimonial.d.ts +20 -0
- package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
- package/dist/src/render/blocks/testimonial.js +29 -0
- package/dist/src/render/blocks/testimonial.js.map +1 -0
- package/dist/src/render/chrome.d.ts +3 -0
- package/dist/src/render/chrome.d.ts.map +1 -0
- package/dist/src/render/chrome.js +114 -0
- package/dist/src/render/chrome.js.map +1 -0
- package/dist/src/render/render-block.d.ts +12 -0
- package/dist/src/render/render-block.d.ts.map +1 -0
- package/dist/src/render/render-block.js +111 -0
- package/dist/src/render/render-block.js.map +1 -0
- package/dist/src/render/term-archive.d.ts +14 -0
- package/dist/src/render/term-archive.d.ts.map +1 -0
- package/dist/src/render/term-archive.js +36 -0
- package/dist/src/render/term-archive.js.map +1 -0
- package/dist/theme.config.d.ts +26 -0
- package/dist/theme.config.d.ts.map +1 -0
- package/dist/theme.config.js +56 -0
- package/dist/theme.config.js.map +1 -0
- package/package.json +57 -0
- package/src/index.ts +19 -0
- package/src/render/blocks/accordion.ts +64 -0
- package/src/render/blocks/collection-list.ts +181 -0
- package/src/render/blocks/cta.ts +37 -0
- package/src/render/blocks/embed.ts +111 -0
- package/src/render/blocks/faq.ts +54 -0
- package/src/render/blocks/feature-grid.ts +68 -0
- package/src/render/blocks/gallery.ts +55 -0
- package/src/render/blocks/hero.ts +55 -0
- package/src/render/blocks/logo-strip.ts +38 -0
- package/src/render/blocks/logos.ts +63 -0
- package/src/render/blocks/media-figure.ts +51 -0
- package/src/render/blocks/pricing-table.ts +69 -0
- package/src/render/blocks/prose.ts +22 -0
- package/src/render/blocks/quote.ts +48 -0
- package/src/render/blocks/stat-counter.ts +49 -0
- package/src/render/blocks/stats.ts +49 -0
- package/src/render/blocks/testimonial.ts +45 -0
- package/src/render/chrome.ts +142 -0
- package/src/render/render-block.ts +155 -0
- package/src/render/term-archive.ts +88 -0
- package/src/styles/archive.css +40 -0
- package/src/styles/base.css +1056 -0
- package/src/styles/blocks.css +1468 -0
- package/src/styles/theme.css +20 -0
- package/src/styles/tokens.css +363 -0
- package/tokens.json +36 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { aspectRatio, h } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* Nothing here contacts a third party before the visitor has consented.
|
|
4
|
+
*
|
|
5
|
+
* When `consentRequired` is true the block renders a self-contained card and
|
|
6
|
+
* an outbound link — no `<iframe>`, no script tag, no preconnect, no poster
|
|
7
|
+
* image fetched from the provider. An embed that "only" loads a thumbnail has
|
|
8
|
+
* already handed the visitor's IP address and a cookie to the provider,
|
|
9
|
+
* which is the exact transfer consent was supposed to gate.
|
|
10
|
+
*
|
|
11
|
+
* The theme ships no consent *button*, because it ships no JavaScript:
|
|
12
|
+
* granting consent is a site-wide decision that belongs to the consent
|
|
13
|
+
* layer, not to a block. The card carries a bracketed provider tag in the
|
|
14
|
+
* mono register — `[ youtube ]` — the theme's own visual shorthand for
|
|
15
|
+
* "something external belongs here".
|
|
16
|
+
*/
|
|
17
|
+
/** `null` means "this provider has no embeddable frame we trust". */
|
|
18
|
+
function frameSource(provider, rawUrl) {
|
|
19
|
+
const url = URL.parse(rawUrl);
|
|
20
|
+
if (url === null)
|
|
21
|
+
return null;
|
|
22
|
+
const segments = url.pathname.split('/').filter((segment) => segment !== '');
|
|
23
|
+
switch (provider) {
|
|
24
|
+
case 'youtube': {
|
|
25
|
+
// `youtube-nocookie.com` is the privacy-preserving host, and the only one
|
|
26
|
+
// this theme will point an iframe at.
|
|
27
|
+
const id = url.hostname.endsWith('youtu.be')
|
|
28
|
+
? segments[0]
|
|
29
|
+
: (url.searchParams.get('v') ?? segments[1]);
|
|
30
|
+
return id === undefined || id === null ? null : `https://www.youtube-nocookie.com/embed/${id}`;
|
|
31
|
+
}
|
|
32
|
+
case 'vimeo': {
|
|
33
|
+
const id = segments.find((segment) => /^\d+$/.test(segment));
|
|
34
|
+
return id === undefined ? null : `https://player.vimeo.com/video/${id}`;
|
|
35
|
+
}
|
|
36
|
+
case 'dailymotion': {
|
|
37
|
+
const id = url.hostname.endsWith('dai.ly') ? segments[0] : segments[segments.length - 1];
|
|
38
|
+
return id === undefined ? null : `https://geo.dailymotion.com/player.html?video=${id}`;
|
|
39
|
+
}
|
|
40
|
+
case 'spotify': {
|
|
41
|
+
const [kind, id] = segments;
|
|
42
|
+
return kind === undefined || id === undefined
|
|
43
|
+
? null
|
|
44
|
+
: `https://open.spotify.com/embed/${kind}/${id}`;
|
|
45
|
+
}
|
|
46
|
+
case 'soundcloud':
|
|
47
|
+
return `https://w.soundcloud.com/player/?url=${encodeURIComponent(rawUrl)}`;
|
|
48
|
+
default:
|
|
49
|
+
// bluesky, mastodon, other: a post embed is a script tag, which this
|
|
50
|
+
// theme does not load. The link card is the rendering.
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function consentCard(block, ctx, reason) {
|
|
55
|
+
return h('div', { class: 'cg-embed__placeholder' }, h('span', { class: 'cg-embed__tag' }, `[ ${block.provider} ]`), h('p', { class: 'cg-embed__notice' }, reason), h('a', {
|
|
56
|
+
class: 'cg-embed__link',
|
|
57
|
+
href: ctx.link(block.url),
|
|
58
|
+
rel: 'noopener noreferrer nofollow',
|
|
59
|
+
}, ctx.t('embed.open', { provider: block.provider })));
|
|
60
|
+
}
|
|
61
|
+
export function renderEmbed(block, ctx) {
|
|
62
|
+
const source = block.consentRequired ? null : frameSource(block.provider, block.url);
|
|
63
|
+
// Video providers are 16:9 unless the editor framed them otherwise; without a
|
|
64
|
+
// ratio the frame would collapse and shift the layout as it loads.
|
|
65
|
+
const ratio = aspectRatio(block.ratio) ?? '16 / 9';
|
|
66
|
+
return h('div', {
|
|
67
|
+
class: 'cg-block cg-embed',
|
|
68
|
+
'data-block': 'embed',
|
|
69
|
+
'data-provider': block.provider,
|
|
70
|
+
'data-consent': block.consentRequired ? 'required' : 'not-required',
|
|
71
|
+
style: `--cg-ratio:${ratio}`,
|
|
72
|
+
}, source === null
|
|
73
|
+
? consentCard(block, ctx, block.consentRequired
|
|
74
|
+
? ctx.t('embed.consentRequired', { provider: block.provider })
|
|
75
|
+
: ctx.t('embed.unsupported', { provider: block.provider }))
|
|
76
|
+
: h('iframe', {
|
|
77
|
+
class: 'cg-embed__frame',
|
|
78
|
+
src: source,
|
|
79
|
+
// An iframe with no accessible name is announced as "frame" and
|
|
80
|
+
// nothing else. WCAG 4.1.2, and the single most common embed defect.
|
|
81
|
+
title: ctx.t('embed.title', { provider: block.provider }),
|
|
82
|
+
loading: 'lazy',
|
|
83
|
+
referrerpolicy: 'strict-origin-when-cross-origin',
|
|
84
|
+
allow: 'accelerometer; clipboard-write; encrypted-media; picture-in-picture; fullscreen',
|
|
85
|
+
allowfullscreen: true,
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=embed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed.js","sourceRoot":"","sources":["../../../../src/render/blocks/embed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faq.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/faq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAEL,KAAK,WAAW,EAGhB,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAA;AA4B3B,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAiB1E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { blockHeadingTag, h, heading, renderRichText, } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* `<details>`/`<summary>` rather than a scripted accordion: expanding,
|
|
4
|
+
* keyboard operation, the expanded state announced to assistive technology
|
|
5
|
+
* and in-page search all come from the browser, at zero bytes of
|
|
6
|
+
* JavaScript.
|
|
7
|
+
*
|
|
8
|
+
* The question is plain text inside `<summary>`, not a heading: a heading
|
|
9
|
+
* nested in a summary is rendered inconsistently across screen readers, and
|
|
10
|
+
* the questions are already reachable as a list under the block's own
|
|
11
|
+
* heading. A CSS-drawn plus mark (rotated to a cross on `[open]`) replaces
|
|
12
|
+
* the native marker rather than a chevron — the theme's own vocabulary of
|
|
13
|
+
* shapes, kept purely visual.
|
|
14
|
+
*/
|
|
15
|
+
function renderItem(item, ctx) {
|
|
16
|
+
return h('li', { class: 'cg-faq__item' }, h('details', { class: 'cg-faq__details' }, h('summary', { class: 'cg-faq__question' }, h('span', {}, item.question)), h('div', { class: 'cg-faq__answer' }, renderRichText(ctx, item.answer))));
|
|
17
|
+
}
|
|
18
|
+
export function renderFaq(block, ctx) {
|
|
19
|
+
return h('section', { class: 'cg-block cg-faq', 'data-block': 'faq' }, block.title === undefined
|
|
20
|
+
? null
|
|
21
|
+
: heading(blockHeadingTag('faq') ?? 'h2', { class: 'cg-faq__title', 'data-field': 'title' }, block.title), h('ul', { class: 'cg-faq__items' }, block.items.map((item) => renderItem(item, ctx))));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=faq.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faq.js","sourceRoot":"","sources":["../../../../src/render/blocks/faq.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EAEf,CAAC,EACD,OAAO,EAEP,cAAc,GACf,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;;;GAYG;AACH,SAAS,UAAU,CAAC,IAAa,EAAE,GAAkB;IACnD,OAAO,CAAC,CACN,IAAI,EACJ,EAAE,KAAK,EAAE,cAAc,EAAE,EACzB,CAAC,CACC,SAAS,EACT,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAC5B,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EACzE,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CACxE,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAe,EAAE,GAAkB;IAC3D,OAAO,CAAC,CACN,SAAS,EACT,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,KAAK,EAAE,EACjD,KAAK,CAAC,KAAK,KAAK,SAAS;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,OAAO,CACL,eAAe,CAAC,KAAK,CAAC,IAAI,IAAI,EAC9B,EAAE,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,EACjD,KAAK,CAAC,KAAK,CACZ,EACL,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,eAAe,EAAE,EAC1B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CACjD,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FeatureGridBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
export declare function renderFeatureGrid(block: FeatureGridBlock, ctx: RenderContext): HtmlElement;
|
|
4
|
+
//# sourceMappingURL=feature-grid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-grid.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/feature-grid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAGL,KAAK,WAAW,EAKhB,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAA;AAqC3B,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAmB1F"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { blockHeadingTag, h, heading, href, nestedHeadingTag, renderIcon, } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The item's title is the link, so the link's accessible name is the
|
|
4
|
+
* feature's name — a bare "learn more" repeated across a grid is the
|
|
5
|
+
* classic failure of WCAG 2.4.4, and the block carries no label field to
|
|
6
|
+
* write one anyway.
|
|
7
|
+
*
|
|
8
|
+
* `icon` names a symbol (`renderIcon`, `theme@1.4`) — drawn small and
|
|
9
|
+
* accent-coloured, decorative (`aria-hidden`, the title already carries the
|
|
10
|
+
* accessible name) — sitting *above* the running index numeral this theme
|
|
11
|
+
* has always drawn from a CSS counter, never replacing it: the numeral is
|
|
12
|
+
* this theme's own editorial device, the icon is the shared vocabulary's.
|
|
13
|
+
* An item with no icon, or one whose name this theme does not recognise,
|
|
14
|
+
* keeps exactly the pre-1.4 numeral-only card.
|
|
15
|
+
*/
|
|
16
|
+
function renderItem(item, ctx, tag) {
|
|
17
|
+
const title = item.link === undefined
|
|
18
|
+
? heading(tag, { class: 'cg-feature__title' }, item.title)
|
|
19
|
+
: heading(tag, { class: 'cg-feature__title' }, h('a', { class: 'cg-feature__link', href: href(ctx, item.link) }, item.title));
|
|
20
|
+
const icon = item.icon === undefined ? null : renderIcon(item.icon, { className: 'cg-feature__icon' });
|
|
21
|
+
return h('li', { class: 'cg-feature', 'data-icon': item.icon }, icon, h('span', { class: 'cg-feature__index', 'aria-hidden': 'true' }), title, item.text === undefined ? null : h('p', { class: 'cg-feature__text' }, item.text));
|
|
22
|
+
}
|
|
23
|
+
export function renderFeatureGrid(block, ctx) {
|
|
24
|
+
const hasTitle = block.title !== undefined;
|
|
25
|
+
const itemTag = nestedHeadingTag('featureGrid', hasTitle);
|
|
26
|
+
return h('section', { class: 'cg-block cg-features', 'data-block': 'featureGrid' }, hasTitle
|
|
27
|
+
? heading(blockHeadingTag('featureGrid') ?? 'h2', { class: 'cg-features__title', 'data-field': 'title' }, block.title ?? '')
|
|
28
|
+
: null, h('ul', { class: 'cg-features__items' }, block.items.map((item) => renderItem(item, ctx, itemTag))));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=feature-grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-grid.js","sourceRoot":"","sources":["../../../../src/render/blocks/feature-grid.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EAGf,CAAC,EACD,OAAO,EACP,IAAI,EACJ,gBAAgB,EAEhB,UAAU,GACX,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;;;;GAaG;AACH,SAAS,UAAU,CAAC,IAAiB,EAAE,GAAkB,EAAE,GAAe;IACxE,MAAM,KAAK,GACT,IAAI,CAAC,IAAI,KAAK,SAAS;QACrB,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;QAC1D,CAAC,CAAC,OAAO,CACL,GAAG,EACH,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAC9B,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAC9E,CAAA;IACP,MAAM,IAAI,GACR,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAA;IAC3F,OAAO,CAAC,CACN,IAAI,EACJ,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,EAC/C,IAAI,EACJ,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,EAChE,KAAK,EACL,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAClF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAuB,EAAE,GAAkB;IAC3E,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAA;IAC1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;IACzD,OAAO,CAAC,CACN,SAAS,EACT,EAAE,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,aAAa,EAAE,EAC9D,QAAQ;QACN,CAAC,CAAC,OAAO,CACL,eAAe,CAAC,aAAa,CAAC,IAAI,IAAI,EACtC,EAAE,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,OAAO,EAAE,EACtD,KAAK,CAAC,KAAK,IAAI,EAAE,CAClB;QACH,CAAC,CAAC,IAAI,EACR,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAC/B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAC1D,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GalleryBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
/**
|
|
4
|
+
* The carousel ships **no JavaScript**. It is a scroll-snapping list, which
|
|
5
|
+
* gives touch swiping, trackpad scrolling and — because the list is focusable
|
|
6
|
+
* and labelled — arrow-key scrolling, with none of the failure modes of a
|
|
7
|
+
* scripted carousel: no auto-advance to fight (WCAG 2.2.2), no focus stolen
|
|
8
|
+
* from an off-screen slide, and it still works before hydration.
|
|
9
|
+
*
|
|
10
|
+
* Every tile carries a decorative index badge (`aria-hidden`, a CSS counter)
|
|
11
|
+
* — a numbered contact sheet rather than a plain image wall, and never a
|
|
12
|
+
* second name for the picture a screen reader would announce.
|
|
13
|
+
*
|
|
14
|
+
* A focusable scrollable region needs an accessible name, or a screen reader
|
|
15
|
+
* announces an unlabelled tab stop; that is WCAG 2.4.3 and 4.1.2 both.
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderGallery(block: GalleryBlock, ctx: RenderContext): HtmlElement;
|
|
18
|
+
//# sourceMappingURL=gallery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gallery.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/gallery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEnF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAqClF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { h, image } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The carousel ships **no JavaScript**. It is a scroll-snapping list, which
|
|
4
|
+
* gives touch swiping, trackpad scrolling and — because the list is focusable
|
|
5
|
+
* and labelled — arrow-key scrolling, with none of the failure modes of a
|
|
6
|
+
* scripted carousel: no auto-advance to fight (WCAG 2.2.2), no focus stolen
|
|
7
|
+
* from an off-screen slide, and it still works before hydration.
|
|
8
|
+
*
|
|
9
|
+
* Every tile carries a decorative index badge (`aria-hidden`, a CSS counter)
|
|
10
|
+
* — a numbered contact sheet rather than a plain image wall, and never a
|
|
11
|
+
* second name for the picture a screen reader would announce.
|
|
12
|
+
*
|
|
13
|
+
* A focusable scrollable region needs an accessible name, or a screen reader
|
|
14
|
+
* announces an unlabelled tab stop; that is WCAG 2.4.3 and 4.1.2 both.
|
|
15
|
+
*/
|
|
16
|
+
export function renderGallery(block, ctx) {
|
|
17
|
+
const items = h('ul', { class: 'cg-gallery__items' }, block.items.map((item) => h('li', { class: 'cg-gallery__item' }, h('span', { class: 'cg-gallery__index', 'aria-hidden': 'true' }), image(ctx, item.media, {
|
|
18
|
+
className: 'cg-gallery__image',
|
|
19
|
+
sizes: '(min-width: 48rem) 22rem, 60vw',
|
|
20
|
+
}))));
|
|
21
|
+
return h('section', {
|
|
22
|
+
class: 'cg-block cg-gallery',
|
|
23
|
+
'data-block': 'gallery',
|
|
24
|
+
'data-layout': block.layout,
|
|
25
|
+
}, block.layout === 'carousel'
|
|
26
|
+
? h('div', {
|
|
27
|
+
class: 'cg-gallery__viewport',
|
|
28
|
+
role: 'region',
|
|
29
|
+
'aria-label': ctx.t('gallery.carousel'),
|
|
30
|
+
tabindex: '0',
|
|
31
|
+
}, items)
|
|
32
|
+
: items);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=gallery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gallery.js","sourceRoot":"","sources":["../../../../src/render/blocks/gallery.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,CAAC,EAAE,KAAK,EAAsB,MAAM,oBAAoB,CAAA;AAEnF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,KAAmB,EAAE,GAAkB;IACnE,MAAM,KAAK,GAAG,CAAC,CACb,IAAI,EACJ,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAC9B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACvB,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAC7B,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,EAChE,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE;QACrB,SAAS,EAAE,mBAAmB;QAC9B,KAAK,EAAE,gCAAgC;KACxC,CAAC,CACH,CACF,CACF,CAAA;IAED,OAAO,CAAC,CACN,SAAS,EACT;QACE,KAAK,EAAE,qBAAqB;QAC5B,YAAY,EAAE,SAAS;QACvB,aAAa,EAAE,KAAK,CAAC,MAAM;KAC5B,EACD,KAAK,CAAC,MAAM,KAAK,UAAU;QACzB,CAAC,CAAC,CAAC,CACC,KAAK,EACL;YACE,KAAK,EAAE,sBAAsB;YAC7B,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC;YACvC,QAAQ,EAAE,GAAG;SACd,EACD,KAAK,CACN;QACH,CAAC,CAAC,KAAK,CACV,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HeroBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
/**
|
|
4
|
+
* The hero carries the page's `h1` — contract B declares `headingLevel: 'h1'`
|
|
5
|
+
* for it, and `renderPage` relies on that to avoid emitting a second one.
|
|
6
|
+
*
|
|
7
|
+
* Structurally distinct from a centred banner: the eyebrow becomes a running
|
|
8
|
+
* index mark set in the mono register (`— eyebrow`), the title is a display
|
|
9
|
+
* headline that overflows its own column on wide screens (`blocks.css` gives
|
|
10
|
+
* it a fluid `clamp()`), and the media is offset into the title's own
|
|
11
|
+
* negative margin rather than sitting in a tidy second column — the overlap
|
|
12
|
+
* is what makes this a poster, not a slide.
|
|
13
|
+
*/
|
|
14
|
+
export declare function renderHero(block: HeroBlock, ctx: RenderContext): HtmlElement;
|
|
15
|
+
//# sourceMappingURL=hero.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hero.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/hero.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAGL,KAAK,WAAW,EAIhB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAgC5E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { actionList, blockHeadingTag, h, heading, image, } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The hero carries the page's `h1` — contract B declares `headingLevel: 'h1'`
|
|
4
|
+
* for it, and `renderPage` relies on that to avoid emitting a second one.
|
|
5
|
+
*
|
|
6
|
+
* Structurally distinct from a centred banner: the eyebrow becomes a running
|
|
7
|
+
* index mark set in the mono register (`— eyebrow`), the title is a display
|
|
8
|
+
* headline that overflows its own column on wide screens (`blocks.css` gives
|
|
9
|
+
* it a fluid `clamp()`), and the media is offset into the title's own
|
|
10
|
+
* negative margin rather than sitting in a tidy second column — the overlap
|
|
11
|
+
* is what makes this a poster, not a slide.
|
|
12
|
+
*/
|
|
13
|
+
export function renderHero(block, ctx) {
|
|
14
|
+
const tag = blockHeadingTag('hero') ?? 'h1';
|
|
15
|
+
return h('section', { class: 'cg-block cg-hero', 'data-block': 'hero' }, h('div', { class: 'cg-hero__frame' }, block.eyebrow === undefined
|
|
16
|
+
? null
|
|
17
|
+
: h('p', { class: 'cg-hero__eyebrow', 'data-field': 'eyebrow' }, block.eyebrow), heading(tag, { class: 'cg-hero__title', 'data-field': 'title' }, block.title), block.subtitle === undefined
|
|
18
|
+
? null
|
|
19
|
+
: h('p', { class: 'cg-hero__subtitle', 'data-field': 'subtitle' }, block.subtitle), actionList(ctx, block.actions, ctx.t('hero.actions'))), block.media === undefined
|
|
20
|
+
? null
|
|
21
|
+
: h('div', { class: 'cg-hero__media' },
|
|
22
|
+
// The only image on the page that is above the fold by construction,
|
|
23
|
+
// so the only one that must not be lazy: lazy-loading the LCP element
|
|
24
|
+
// is a measured Lighthouse regression, not a theoretical one.
|
|
25
|
+
image(ctx, block.media, {
|
|
26
|
+
className: 'cg-hero__image',
|
|
27
|
+
loading: 'eager',
|
|
28
|
+
sizes: '(min-width: 64rem) 46vw, 100vw',
|
|
29
|
+
})));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=hero.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hero.js","sourceRoot":"","sources":["../../../../src/render/blocks/hero.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,eAAe,EAEf,CAAC,EACD,OAAO,EACP,KAAK,GAEN,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,KAAgB,EAAE,GAAkB;IAC7D,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,IAAI,CAAA;IAC3C,OAAO,CAAC,CACN,SAAS,EACT,EAAE,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAAE,EACnD,CAAC,CACC,KAAK,EACL,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAC3B,KAAK,CAAC,OAAO,KAAK,SAAS;QACzB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,EACjF,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,EAC7E,KAAK,CAAC,QAAQ,KAAK,SAAS;QAC1B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,EACpF,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CACtD,EACD,KAAK,CAAC,KAAK,KAAK,SAAS;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,KAAK,EACL,EAAE,KAAK,EAAE,gBAAgB,EAAE;QAC3B,qEAAqE;QACrE,sEAAsE;QACtE,8DAA8D;QAC9D,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE;YACtB,SAAS,EAAE,gBAAgB;YAC3B,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,gCAAgC;SACxC,CAAC,CACH,CACN,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logo-strip.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/logo-strip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAuBnF,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAatF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { h, image } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* Lighter-weight than `logos` on purpose (RFC 0001): no per-mark `name`/
|
|
4
|
+
* `url`, so no link, no accessible-name field to write, and no numbered
|
|
5
|
+
* ledger row — this is the quieter "as seen in" strip, marks set edge to
|
|
6
|
+
* edge with no dividers, desaturated exactly like `logos.ts`'s own marks
|
|
7
|
+
* (the theme's one visual language for "a logo not currently in focus").
|
|
8
|
+
* The image's own alt text (set once, in the media library) is what names
|
|
9
|
+
* each mark, same as `logos.ts` falls back to when a link is absent — never
|
|
10
|
+
* invented here, which is why `image` is called with no `altFrom`.
|
|
11
|
+
*/
|
|
12
|
+
function renderItem(item, ctx) {
|
|
13
|
+
return h('li', { class: 'cg-logostrip__item' }, image(ctx, item.media, {
|
|
14
|
+
className: 'cg-logostrip__image',
|
|
15
|
+
variant: { fit: 'contain' },
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
export function renderLogoStrip(block, ctx) {
|
|
19
|
+
return h('figure', { class: 'cg-block cg-logostrip', 'data-block': 'logoStrip' }, h('ul', { class: 'cg-logostrip__items' }, block.logos.map((item) => renderItem(item, ctx))), block.caption === undefined
|
|
20
|
+
? null
|
|
21
|
+
: h('figcaption', { class: 'cg-logostrip__caption', 'data-field': 'caption' }, block.caption));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=logo-strip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logo-strip.js","sourceRoot":"","sources":["../../../../src/render/blocks/logo-strip.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,CAAC,EAAE,KAAK,EAAsB,MAAM,oBAAoB,CAAA;AAEnF;;;;;;;;;GASG;AACH,SAAS,UAAU,CAAC,IAAmB,EAAE,GAAkB;IACzD,OAAO,CAAC,CACN,IAAI,EACJ,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAC/B,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE;QACrB,SAAS,EAAE,qBAAqB;QAChC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE;KAC5B,CAAC,CACH,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,GAAkB;IACvE,OAAO,CAAC,CACN,QAAQ,EACR,EAAE,KAAK,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,EAC7D,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAChC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CACjD,EACD,KAAK,CAAC,OAAO,KAAK,SAAS;QACzB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAChG,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logos.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/logos.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAEL,KAAK,WAAW,EAIhB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AAqC3B,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAiB9E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { blockHeadingTag, h, heading, image, } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* Contract B says the organisation's name **is** the accessible name of the
|
|
4
|
+
* link. So the logo image carries it as alt text when the media entity has
|
|
5
|
+
* none, and no visually hidden duplicate is added: a link whose only content
|
|
6
|
+
* is an image with alt text is already named.
|
|
7
|
+
*
|
|
8
|
+
* Rendered as a single-row ledger rather than a grid of tiles — a running
|
|
9
|
+
* mono index beside each mark, in a desaturated register that resolves to
|
|
10
|
+
* full ink only on hover or focus (`blocks.css`), which is the theme's own
|
|
11
|
+
* take on the "selected clients" strip.
|
|
12
|
+
*/
|
|
13
|
+
function renderItem(item, ctx, index) {
|
|
14
|
+
const logo = image(ctx, item.media, {
|
|
15
|
+
className: 'cg-logo__image',
|
|
16
|
+
altFrom: item.name,
|
|
17
|
+
variant: { fit: 'contain' },
|
|
18
|
+
});
|
|
19
|
+
return h('li', { class: 'cg-logo' }, h('span', { class: 'cg-logo__index', 'aria-hidden': 'true' }, String(index + 1).padStart(2, '0')), item.url === undefined
|
|
20
|
+
? logo
|
|
21
|
+
: h('a', { class: 'cg-logo__link', href: ctx.link(item.url), rel: 'noopener noreferrer' }, logo));
|
|
22
|
+
}
|
|
23
|
+
export function renderLogos(block, ctx) {
|
|
24
|
+
return h('section', { class: 'cg-block cg-logos', 'data-block': 'logos' }, block.title === undefined
|
|
25
|
+
? null
|
|
26
|
+
: heading(blockHeadingTag('logos') ?? 'h2', { class: 'cg-logos__title', 'data-field': 'title' }, block.title), h('ul', { class: 'cg-logos__items' }, block.items.map((item, index) => renderItem(item, ctx, index))));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=logos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logos.js","sourceRoot":"","sources":["../../../../src/render/blocks/logos.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EAEf,CAAC,EACD,OAAO,EACP,KAAK,GAEN,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;;;GAUG;AACH,SAAS,UAAU,CAAC,IAAc,EAAE,GAAkB,EAAE,KAAa;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE;QAClC,SAAS,EAAE,gBAAgB;QAC3B,OAAO,EAAE,IAAI,CAAC,IAAI;QAClB,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE;KAC5B,CAAC,CAAA;IACF,OAAO,CAAC,CACN,IAAI,EACJ,EAAE,KAAK,EAAE,SAAS,EAAE,EACpB,CAAC,CACC,MAAM,EACN,EAAE,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE,EAClD,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CACnC,EACD,IAAI,CAAC,GAAG,KAAK,SAAS;QACpB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,GAAG,EACH,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,qBAAqB,EAAE,EAChF,IAAI,CACL,CACN,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,GAAkB;IAC/D,OAAO,CAAC,CACN,SAAS,EACT,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,OAAO,EAAE,EACrD,KAAK,CAAC,KAAK,KAAK,SAAS;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,OAAO,CACL,eAAe,CAAC,OAAO,CAAC,IAAI,IAAI,EAChC,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,EAAE,EACnD,KAAK,CAAC,KAAK,CACZ,EACL,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAC5B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAC/D,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MediaFigureBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
/**
|
|
4
|
+
* `<figure>`/`<figcaption>` rather than a div and a paragraph: the
|
|
5
|
+
* association between the picture and its caption is then in the markup,
|
|
6
|
+
* and a screen reader announces the caption as belonging to the image
|
|
7
|
+
* instead of as loose text after it.
|
|
8
|
+
*
|
|
9
|
+
* The "Fig. 01" plate number that precedes the caption is drawn entirely
|
|
10
|
+
* from a CSS counter (`counter-increment: cg-figure` in `blocks.css`) — it
|
|
11
|
+
* is not stored data, so it renumbers itself as figures are added or
|
|
12
|
+
* removed and never needs updating here.
|
|
13
|
+
*
|
|
14
|
+
* `align` is written as a data attribute, never as a class: contract B's
|
|
15
|
+
* values are `start`/`end`, an intent that mirrors in right-to-left
|
|
16
|
+
* locales, and the skin decides what it means.
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderMediaFigure(block: MediaFigureBlock, ctx: RenderContext): HtmlElement;
|
|
19
|
+
//# sourceMappingURL=media-figure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-figure.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/media-figure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAe,KAAK,WAAW,EAAY,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEhG;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAgC1F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { aspectRatio, h, image } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* `<figure>`/`<figcaption>` rather than a div and a paragraph: the
|
|
4
|
+
* association between the picture and its caption is then in the markup,
|
|
5
|
+
* and a screen reader announces the caption as belonging to the image
|
|
6
|
+
* instead of as loose text after it.
|
|
7
|
+
*
|
|
8
|
+
* The "Fig. 01" plate number that precedes the caption is drawn entirely
|
|
9
|
+
* from a CSS counter (`counter-increment: cg-figure` in `blocks.css`) — it
|
|
10
|
+
* is not stored data, so it renumbers itself as figures are added or
|
|
11
|
+
* removed and never needs updating here.
|
|
12
|
+
*
|
|
13
|
+
* `align` is written as a data attribute, never as a class: contract B's
|
|
14
|
+
* values are `start`/`end`, an intent that mirrors in right-to-left
|
|
15
|
+
* locales, and the skin decides what it means.
|
|
16
|
+
*/
|
|
17
|
+
export function renderMediaFigure(block, ctx) {
|
|
18
|
+
const ratio = aspectRatio(block.ratio);
|
|
19
|
+
const hasCaption = block.caption !== undefined || block.credit !== undefined;
|
|
20
|
+
return h('figure', {
|
|
21
|
+
class: 'cg-block cg-figure',
|
|
22
|
+
'data-block': 'mediaFigure',
|
|
23
|
+
'data-align': block.align ?? 'center',
|
|
24
|
+
style: ratio === undefined ? undefined : `--cg-ratio:${ratio}`,
|
|
25
|
+
}, h('div', { class: 'cg-figure__frame' }, image(ctx, block.media, {
|
|
26
|
+
className: 'cg-figure__media',
|
|
27
|
+
sizes: '(min-width: 48rem) 42rem, 100vw',
|
|
28
|
+
})), hasCaption
|
|
29
|
+
? h('figcaption', { class: 'cg-figure__caption' }, block.caption === undefined
|
|
30
|
+
? null
|
|
31
|
+
: h('span', { class: 'cg-figure__plate' }, block.caption), block.credit === undefined
|
|
32
|
+
? null
|
|
33
|
+
: h('span', { class: 'cg-figure__credit', 'data-field': 'credit' }, block.credit))
|
|
34
|
+
: null);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=media-figure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-figure.js","sourceRoot":"","sources":["../../../../src/render/blocks/media-figure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAoB,CAAC,EAAE,KAAK,EAAsB,MAAM,oBAAoB,CAAA;AAEhG;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAuB,EAAE,GAAkB;IAC3E,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;IAC5E,OAAO,CAAC,CACN,QAAQ,EACR;QACE,KAAK,EAAE,oBAAoB;QAC3B,YAAY,EAAE,aAAa;QAC3B,YAAY,EAAE,KAAK,CAAC,KAAK,IAAI,QAAQ;QACrC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,KAAK,EAAE;KAC/D,EACD,CAAC,CACC,KAAK,EACL,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAC7B,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE;QACtB,SAAS,EAAE,kBAAkB;QAC7B,KAAK,EAAE,iCAAiC;KACzC,CAAC,CACH,EACD,UAAU;QACR,CAAC,CAAC,CAAC,CACC,YAAY,EACZ,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAC/B,KAAK,CAAC,OAAO,KAAK,SAAS;YACzB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,EAC3D,KAAK,CAAC,MAAM,KAAK,SAAS;YACxB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CACpF;QACH,CAAC,CAAC,IAAI,CACT,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PricingTableBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
export declare function renderPricingTable(block: PricingTableBlock, ctx: RenderContext): HtmlElement;
|
|
4
|
+
//# sourceMappingURL=pricing-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing-table.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/pricing-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAe,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAIL,KAAK,WAAW,EAIhB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AAuC3B,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAmB5F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { actionLink, blockHeadingTag, h, heading, nestedHeadingTag, } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* `highlighted` is an editorial signal, never a colour (RFC 0001's own
|
|
4
|
+
* comment on the field): it is written as `data-highlighted="true"` for the
|
|
5
|
+
* skin to key off, and the tier additionally carries `aria-current="true"`
|
|
6
|
+
* — the closest native semantic for "the one the author means you to pick"
|
|
7
|
+
* among a set of siblings.
|
|
8
|
+
*/
|
|
9
|
+
function renderTier(tier, ctx, tag) {
|
|
10
|
+
return h('li', {
|
|
11
|
+
class: 'cg-pricing__tier',
|
|
12
|
+
'data-highlighted': tier.highlighted === true ? 'true' : undefined,
|
|
13
|
+
'aria-current': tier.highlighted === true ? 'true' : undefined,
|
|
14
|
+
}, heading(tag, { class: 'cg-pricing__name' }, tier.name), h('p', { class: 'cg-pricing__price' }, tier.price, tier.interval === undefined
|
|
15
|
+
? null
|
|
16
|
+
: h('span', { class: 'cg-pricing__interval' }, tier.interval)), tier.features.length === 0
|
|
17
|
+
? null
|
|
18
|
+
: h('ul', { class: 'cg-pricing__features' }, tier.features.map((feature) => h('li', {}, feature))), tier.action === undefined
|
|
19
|
+
? null
|
|
20
|
+
: h('div', { class: 'cg-pricing__action' }, actionLink(ctx, tier.action)));
|
|
21
|
+
}
|
|
22
|
+
export function renderPricingTable(block, ctx) {
|
|
23
|
+
const hasTitle = block.title !== undefined;
|
|
24
|
+
const tierTag = nestedHeadingTag('pricingTable', hasTitle);
|
|
25
|
+
return h('section', { class: 'cg-block cg-pricing', 'data-block': 'pricingTable' }, hasTitle
|
|
26
|
+
? heading(blockHeadingTag('pricingTable') ?? 'h2', { class: 'cg-pricing__title', 'data-field': 'title' }, block.title ?? '')
|
|
27
|
+
: null, h('ul', { class: 'cg-pricing__tiers' }, block.tiers.map((tier) => renderTier(tier, ctx, tierTag))));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=pricing-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing-table.js","sourceRoot":"","sources":["../../../../src/render/blocks/pricing-table.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,eAAe,EAGf,CAAC,EACD,OAAO,EACP,gBAAgB,GAEjB,MAAM,oBAAoB,CAAA;AAE3B;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,IAAiB,EAAE,GAAkB,EAAE,GAAe;IACxE,OAAO,CAAC,CACN,IAAI,EACJ;QACE,KAAK,EAAE,kBAAkB;QACzB,kBAAkB,EAAE,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAClE,cAAc,EAAE,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;KAC/D,EACD,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EACtD,CAAC,CACC,GAAG,EACH,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAC9B,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,QAAQ,KAAK,SAAS;QACzB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAChE,EACD,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QACxB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,sBAAsB,EAAE,EACjC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CACrD,EACL,IAAI,CAAC,MAAM,KAAK,SAAS;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAC5E,CAAA;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAwB,EAAE,GAAkB;IAC7E,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAA;IAC1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;IAC1D,OAAO,CAAC,CACN,SAAS,EACT,EAAE,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,cAAc,EAAE,EAC9D,QAAQ;QACN,CAAC,CAAC,OAAO,CACL,eAAe,CAAC,cAAc,CAAC,IAAI,IAAI,EACvC,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,OAAO,EAAE,EACrD,KAAK,CAAC,KAAK,IAAI,EAAE,CAClB;QACH,CAAC,CAAC,IAAI,EACR,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAC9B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAC1D,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ProseBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
/**
|
|
4
|
+
* `prose` declares `headingLevel: 'none'`: it contributes no heading of its
|
|
5
|
+
* own. Whatever headings appear come from the rich text document, whose
|
|
6
|
+
* vocabulary starts at `h2`.
|
|
7
|
+
*
|
|
8
|
+
* The wrapper is deliberately plain — a rich text document is arbitrary
|
|
9
|
+
* editorial content, and the only honest DOM shape for arbitrary content is
|
|
10
|
+
* "here it is". The distinctive editorial treatment (a dropped first
|
|
11
|
+
* capital, an oversized `h2`, a hairline-and-number rule before each
|
|
12
|
+
* heading) lives entirely in `blocks.css`, driven off the very structure
|
|
13
|
+
* `renderRichText` already produces.
|
|
14
|
+
*/
|
|
15
|
+
export declare function renderProse(block: ProseBlock, ctx: RenderContext): HtmlElement;
|
|
16
|
+
//# sourceMappingURL=prose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prose.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/prose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,KAAK,WAAW,EAAK,KAAK,aAAa,EAAkB,MAAM,oBAAoB,CAAA;AAE5F;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAM9E"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { h, renderRichText } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* `prose` declares `headingLevel: 'none'`: it contributes no heading of its
|
|
4
|
+
* own. Whatever headings appear come from the rich text document, whose
|
|
5
|
+
* vocabulary starts at `h2`.
|
|
6
|
+
*
|
|
7
|
+
* The wrapper is deliberately plain — a rich text document is arbitrary
|
|
8
|
+
* editorial content, and the only honest DOM shape for arbitrary content is
|
|
9
|
+
* "here it is". The distinctive editorial treatment (a dropped first
|
|
10
|
+
* capital, an oversized `h2`, a hairline-and-number rule before each
|
|
11
|
+
* heading) lives entirely in `blocks.css`, driven off the very structure
|
|
12
|
+
* `renderRichText` already produces.
|
|
13
|
+
*/
|
|
14
|
+
export function renderProse(block, ctx) {
|
|
15
|
+
return h('div', { class: 'cg-block cg-prose', 'data-block': 'prose' }, renderRichText(ctx, block.body));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=prose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prose.js","sourceRoot":"","sources":["../../../../src/render/blocks/prose.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,CAAC,EAAsB,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAE5F;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,GAAkB;IAC/D,OAAO,CAAC,CACN,KAAK,EACL,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,OAAO,EAAE,EACrD,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAChC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { QuoteBlock } from '@cogenta/blocks';
|
|
2
|
+
import { type HtmlElement, type RenderContext } from '@cogenta/theme-kit';
|
|
3
|
+
/**
|
|
4
|
+
* `<figure><blockquote>…</blockquote><figcaption>` is the attribution
|
|
5
|
+
* pattern the HTML spec prescribes: putting the author inside the
|
|
6
|
+
* `<blockquote>` would claim the author's name is part of what was said.
|
|
7
|
+
*
|
|
8
|
+
* Set left-aligned at display scale rather than centred — a pull quote that
|
|
9
|
+
* fills the column edge to edge, the way a magazine breaks one out of a
|
|
10
|
+
* feature. The attribution is set in the mono register, the theme's
|
|
11
|
+
* register for credits and metadata.
|
|
12
|
+
*
|
|
13
|
+
* The avatar is decorative here — the name is right beside it in text — so
|
|
14
|
+
* its media entity's alt text is expected to be empty. `image` still writes
|
|
15
|
+
* the attribute either way.
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderQuote(block: QuoteBlock, ctx: RenderContext): HtmlElement;
|
|
18
|
+
//# sourceMappingURL=quote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../../../../src/render/blocks/quote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,KAAK,WAAW,EAAY,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEnF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CA8B9E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { h, image } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* `<figure><blockquote>…</blockquote><figcaption>` is the attribution
|
|
4
|
+
* pattern the HTML spec prescribes: putting the author inside the
|
|
5
|
+
* `<blockquote>` would claim the author's name is part of what was said.
|
|
6
|
+
*
|
|
7
|
+
* Set left-aligned at display scale rather than centred — a pull quote that
|
|
8
|
+
* fills the column edge to edge, the way a magazine breaks one out of a
|
|
9
|
+
* feature. The attribution is set in the mono register, the theme's
|
|
10
|
+
* register for credits and metadata.
|
|
11
|
+
*
|
|
12
|
+
* The avatar is decorative here — the name is right beside it in text — so
|
|
13
|
+
* its media entity's alt text is expected to be empty. `image` still writes
|
|
14
|
+
* the attribute either way.
|
|
15
|
+
*/
|
|
16
|
+
export function renderQuote(block, ctx) {
|
|
17
|
+
const hasAttribution = block.author !== undefined || block.role !== undefined || block.avatar !== undefined;
|
|
18
|
+
return h('figure', { class: 'cg-block cg-quote', 'data-block': 'quote' }, h('blockquote', { class: 'cg-quote__text' }, h('p', { 'data-field': 'text' }, block.text)), hasAttribution
|
|
19
|
+
? h('figcaption', { class: 'cg-quote__attribution' }, block.avatar === undefined
|
|
20
|
+
? null
|
|
21
|
+
: image(ctx, block.avatar, {
|
|
22
|
+
className: 'cg-quote__avatar',
|
|
23
|
+
variant: { width: 96, height: 96, fit: 'cover' },
|
|
24
|
+
}), h('span', { class: 'cg-quote__names' }, block.author === undefined
|
|
25
|
+
? null
|
|
26
|
+
: h('span', { class: 'cg-quote__author', 'data-field': 'author' }, block.author), block.role === undefined
|
|
27
|
+
? null
|
|
28
|
+
: h('span', { class: 'cg-quote__role', 'data-field': 'role' }, block.role)))
|
|
29
|
+
: null);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=quote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../../../../src/render/blocks/quote.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,CAAC,EAAE,KAAK,EAAsB,MAAM,oBAAoB,CAAA;AAEnF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,GAAkB;IAC/D,MAAM,cAAc,GAClB,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAA;IACtF,OAAO,CAAC,CACN,QAAQ,EACR,EAAE,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,OAAO,EAAE,EACrD,CAAC,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAC1F,cAAc;QACZ,CAAC,CAAC,CAAC,CACC,YAAY,EACZ,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAClC,KAAK,CAAC,MAAM,KAAK,SAAS;YACxB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE;gBACvB,SAAS,EAAE,kBAAkB;gBAC7B,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;aACjD,CAAC,EACN,CAAC,CACC,MAAM,EACN,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAC5B,KAAK,CAAC,MAAM,KAAK,SAAS;YACxB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,EAClF,KAAK,CAAC,IAAI,KAAK,SAAS;YACtB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAC7E,CACF;QACH,CAAC,CAAC,IAAI,CACT,CAAA;AACH,CAAC"}
|