@cogenta/theme-canonical 0.2.1 → 1.1.0
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 +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/render/actions.d.ts +2 -16
- package/dist/src/render/actions.d.ts.map +1 -1
- package/dist/src/render/actions.js +2 -42
- package/dist/src/render/actions.js.map +1 -1
- package/dist/src/render/blocks/accordion.d.ts +5 -0
- package/dist/src/render/blocks/accordion.d.ts.map +1 -0
- package/dist/src/render/blocks/accordion.js +19 -0
- package/dist/src/render/blocks/accordion.js.map +1 -0
- package/dist/src/render/blocks/collection-list.d.ts +9 -7
- package/dist/src/render/blocks/collection-list.d.ts.map +1 -1
- package/dist/src/render/blocks/collection-list.js +8 -14
- package/dist/src/render/blocks/collection-list.js.map +1 -1
- package/dist/src/render/blocks/feature-grid.d.ts.map +1 -1
- package/dist/src/render/blocks/feature-grid.js +7 -2
- package/dist/src/render/blocks/feature-grid.js.map +1 -1
- package/dist/src/render/blocks/logo-strip.d.ts +5 -0
- package/dist/src/render/blocks/logo-strip.d.ts.map +1 -0
- package/dist/src/render/blocks/logo-strip.js +18 -0
- package/dist/src/render/blocks/logo-strip.js.map +1 -0
- package/dist/src/render/blocks/pricing-table.d.ts +5 -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/stat-counter.d.ts +5 -0
- package/dist/src/render/blocks/stat-counter.d.ts.map +1 -0
- package/dist/src/render/blocks/stat-counter.js +17 -0
- package/dist/src/render/blocks/stat-counter.js.map +1 -0
- package/dist/src/render/blocks/testimonial.d.ts +14 -0
- package/dist/src/render/blocks/testimonial.d.ts.map +1 -0
- package/dist/src/render/blocks/testimonial.js +24 -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 +82 -0
- package/dist/src/render/chrome.js.map +1 -0
- package/dist/src/render/comments.d.ts +3 -0
- package/dist/src/render/comments.d.ts.map +1 -0
- package/dist/src/render/comments.js +3 -0
- package/dist/src/render/comments.js.map +1 -0
- package/dist/src/render/entry.d.ts +2 -6
- package/dist/src/render/entry.d.ts.map +1 -1
- package/dist/src/render/entry.js +2 -34
- package/dist/src/render/entry.js.map +1 -1
- package/dist/src/render/heading.d.ts +2 -13
- package/dist/src/render/heading.d.ts.map +1 -1
- package/dist/src/render/heading.js +2 -33
- package/dist/src/render/heading.js.map +1 -1
- package/dist/src/render/html.d.ts +2 -43
- package/dist/src/render/html.d.ts.map +1 -1
- package/dist/src/render/html.js +2 -95
- package/dist/src/render/html.js.map +1 -1
- package/dist/src/render/icons.d.ts +3 -0
- package/dist/src/render/icons.d.ts.map +1 -0
- package/dist/src/render/icons.js +3 -0
- package/dist/src/render/icons.js.map +1 -0
- package/dist/src/render/media.d.ts +2 -31
- package/dist/src/render/media.d.ts.map +1 -1
- package/dist/src/render/media.js +2 -41
- package/dist/src/render/media.js.map +1 -1
- package/dist/src/render/render-block.d.ts +11 -22
- package/dist/src/render/render-block.d.ts.map +1 -1
- package/dist/src/render/render-block.js +63 -62
- package/dist/src/render/render-block.js.map +1 -1
- package/dist/src/render/rich-text.d.ts +2 -4
- package/dist/src/render/rich-text.d.ts.map +1 -1
- package/dist/src/render/rich-text.js +2 -104
- package/dist/src/render/rich-text.js.map +1 -1
- package/dist/src/render/term-archive.d.ts +12 -0
- package/dist/src/render/term-archive.d.ts.map +1 -0
- package/dist/src/render/term-archive.js +39 -0
- package/dist/src/render/term-archive.js.map +1 -0
- package/dist/src/theme-contract.d.ts +10 -162
- package/dist/src/theme-contract.d.ts.map +1 -1
- package/dist/src/theme-contract.js +9 -17
- package/dist/src/theme-contract.js.map +1 -1
- package/dist/theme.config.d.ts +5 -16
- package/dist/theme.config.d.ts.map +1 -1
- package/dist/theme.config.js +16 -5
- package/dist/theme.config.js.map +1 -1
- package/package.json +4 -2
- package/src/index.ts +4 -0
- package/src/render/actions.ts +2 -57
- package/src/render/blocks/accordion.ts +44 -0
- package/src/render/blocks/collection-list.ts +9 -15
- package/src/render/blocks/feature-grid.ts +11 -2
- package/src/render/blocks/logo-strip.ts +38 -0
- package/src/render/blocks/pricing-table.ts +65 -0
- package/src/render/blocks/stat-counter.ts +34 -0
- package/src/render/blocks/testimonial.ts +41 -0
- package/src/render/chrome.ts +105 -0
- package/src/render/comments.ts +6 -0
- package/src/render/entry.ts +2 -40
- package/src/render/heading.ts +7 -44
- package/src/render/html.ts +15 -122
- package/src/render/icons.ts +2 -0
- package/src/render/media.ts +2 -62
- package/src/render/render-block.ts +85 -75
- package/src/render/rich-text.ts +2 -150
- package/src/render/term-archive.ts +85 -0
- package/src/styles/archive.css +40 -0
- package/src/styles/base.css +525 -3
- package/src/styles/blocks.css +344 -14
- package/src/styles/theme.css +1 -0
- package/src/theme-contract.ts +23 -155
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-block.js","sourceRoot":"","sources":["../../../src/render/render-block.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"render-block.js","sourceRoot":"","sources":["../../../src/render/render-block.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { type HtmlNode } from './html.js';
|
|
4
|
-
export declare function renderRichText(ctx: RenderContext, document: RichTextDocument): readonly HtmlNode[];
|
|
1
|
+
/** Re-exported from `@cogenta/theme-kit` — see that package's `rich-text.ts`. */
|
|
2
|
+
export { renderRichText } from '@cogenta/theme-kit';
|
|
5
3
|
//# sourceMappingURL=rich-text.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text.d.ts","sourceRoot":"","sources":["../../../src/render/rich-text.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"rich-text.d.ts","sourceRoot":"","sources":["../../../src/render/rich-text.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -1,105 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const KNOWN_MARKS = new Map([
|
|
4
|
-
['strong', 'strong'],
|
|
5
|
-
['em', 'em'],
|
|
6
|
-
['code', 'code'],
|
|
7
|
-
]);
|
|
8
|
-
function applyMark(ctx, mark, markDefs, child) {
|
|
9
|
-
const tag = KNOWN_MARKS.get(mark);
|
|
10
|
-
if (tag !== undefined)
|
|
11
|
-
return h(tag, {}, child);
|
|
12
|
-
const definition = markDefs.find((candidate) => candidate._key === mark);
|
|
13
|
-
if (definition === undefined) {
|
|
14
|
-
// An annotation this theme does not know stays text. Guessing markup for it
|
|
15
|
-
// is how a mark becomes an injection vector.
|
|
16
|
-
return child;
|
|
17
|
-
}
|
|
18
|
-
if (definition._type === 'link') {
|
|
19
|
-
return h('a', { href: ctx.link(definition.href), rel: definition.rel }, child);
|
|
20
|
-
}
|
|
21
|
-
return h('a', { href: ctx.link({ collection: definition.collection, id: definition.id }) }, child);
|
|
22
|
-
}
|
|
23
|
-
function renderSpan(ctx, span, markDefs) {
|
|
24
|
-
let node = text(span.text);
|
|
25
|
-
// Applied in reverse so the first mark ends up outermost, which keeps
|
|
26
|
-
// `['link', 'strong']` rendering as a link containing bold text.
|
|
27
|
-
for (const mark of [...span.marks].reverse()) {
|
|
28
|
-
node = applyMark(ctx, mark, markDefs, node);
|
|
29
|
-
}
|
|
30
|
-
return node;
|
|
31
|
-
}
|
|
32
|
-
function renderChildren(ctx, block) {
|
|
33
|
-
return block.children.map((span) => renderSpan(ctx, span, block.markDefs));
|
|
34
|
-
}
|
|
35
|
-
function isListItem(node) {
|
|
36
|
-
return node !== undefined && node._type === 'block' && node.listItem !== undefined;
|
|
37
|
-
}
|
|
38
|
-
function levelOf(node) {
|
|
39
|
-
return node.level ?? 1;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Builds one list, and every list nested inside it, from a run of consecutive
|
|
43
|
-
* list items. A nested list lives *inside* the preceding `<li>` — putting it
|
|
44
|
-
* beside one produces a list whose items do not match what is announced.
|
|
45
|
-
*/
|
|
46
|
-
function buildList(ctx, nodes, start, level) {
|
|
47
|
-
const first = nodes[start];
|
|
48
|
-
if (!isListItem(first))
|
|
49
|
-
return { node: text(''), next: start + 1 };
|
|
50
|
-
const kind = first.listItem;
|
|
51
|
-
const items = [];
|
|
52
|
-
let index = start;
|
|
53
|
-
while (index < nodes.length) {
|
|
54
|
-
const node = nodes[index];
|
|
55
|
-
if (!isListItem(node))
|
|
56
|
-
break;
|
|
57
|
-
const nodeLevel = levelOf(node);
|
|
58
|
-
if (nodeLevel < level || node.listItem !== kind)
|
|
59
|
-
break;
|
|
60
|
-
if (nodeLevel > level) {
|
|
61
|
-
const nested = buildList(ctx, nodes, index, nodeLevel);
|
|
62
|
-
const last = items.pop();
|
|
63
|
-
items.push(last === undefined || last.kind !== 'element'
|
|
64
|
-
? h('li', {}, nested.node)
|
|
65
|
-
: h('li', last.attrs, ...last.children, nested.node));
|
|
66
|
-
index = nested.next;
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
items.push(h('li', {}, ...renderChildren(ctx, node)));
|
|
70
|
-
index += 1;
|
|
71
|
-
}
|
|
72
|
-
return { node: h(kind === 'number' ? 'ol' : 'ul', {}, items), next: index };
|
|
73
|
-
}
|
|
74
|
-
function renderTextBlock(ctx, block) {
|
|
75
|
-
const children = renderChildren(ctx, block);
|
|
76
|
-
if (block.style === 'blockquote')
|
|
77
|
-
return h('blockquote', {}, h('p', {}, ...children));
|
|
78
|
-
if (block.style === 'normal')
|
|
79
|
-
return h('p', {}, ...children);
|
|
80
|
-
return h(block.style, {}, ...children);
|
|
81
|
-
}
|
|
82
|
-
export function renderRichText(ctx, document) {
|
|
83
|
-
const out = [];
|
|
84
|
-
let index = 0;
|
|
85
|
-
while (index < document.length) {
|
|
86
|
-
const node = document[index];
|
|
87
|
-
if (node === undefined)
|
|
88
|
-
break;
|
|
89
|
-
if (isListItem(node)) {
|
|
90
|
-
const list = buildList(ctx, document, index, levelOf(node));
|
|
91
|
-
out.push(list.node);
|
|
92
|
-
index = list.next;
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (node._type === 'media') {
|
|
96
|
-
out.push(h('figure', { class: 'cg-prose__figure' }, image(ctx, node.id, { sizes: '(min-width: 45rem) 40rem, 100vw' }), node.caption === undefined ? null : h('figcaption', {}, node.caption)));
|
|
97
|
-
index += 1;
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
out.push(renderTextBlock(ctx, node));
|
|
101
|
-
index += 1;
|
|
102
|
-
}
|
|
103
|
-
return out;
|
|
104
|
-
}
|
|
1
|
+
/** Re-exported from `@cogenta/theme-kit` — see that package's `rich-text.ts`. */
|
|
2
|
+
export { renderRichText } from '@cogenta/theme-kit';
|
|
105
3
|
//# sourceMappingURL=rich-text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text.js","sourceRoot":"","sources":["../../../src/render/rich-text.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rich-text.js","sourceRoot":"","sources":["../../../src/render/rich-text.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type HtmlElement, type TermArchiveInput } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The taxonomy-term archive (contract D `theme@1.3`).
|
|
4
|
+
*
|
|
5
|
+
* Built from this theme's *own* entry-card classes — the same `cg-entry`
|
|
6
|
+
* markup `collectionList` already renders — rather than a new set of
|
|
7
|
+
* archive-only classes: an archive of articles should look like a list of
|
|
8
|
+
* articles on this theme, and reusing the classes is what guarantees that
|
|
9
|
+
* without a second stylesheet to keep in step.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderTermArchive(input: TermArchiveInput): HtmlElement;
|
|
12
|
+
//# sourceMappingURL=term-archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"term-archive.d.ts","sourceRoot":"","sources":["../../../src/render/term-archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAK,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE/E;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAsDtE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { h } from '@cogenta/theme-kit';
|
|
2
|
+
/**
|
|
3
|
+
* The taxonomy-term archive (contract D `theme@1.3`).
|
|
4
|
+
*
|
|
5
|
+
* Built from this theme's *own* entry-card classes — the same `cg-entry`
|
|
6
|
+
* markup `collectionList` already renders — rather than a new set of
|
|
7
|
+
* archive-only classes: an archive of articles should look like a list of
|
|
8
|
+
* articles on this theme, and reusing the classes is what guarantees that
|
|
9
|
+
* without a second stylesheet to keep in step.
|
|
10
|
+
*/
|
|
11
|
+
export function renderTermArchive(input) {
|
|
12
|
+
const items = input.entries.map((entry) => h('li', { class: 'cg-entry' }, h('div', { class: 'cg-entry__body' }, h('h2', { class: 'cg-entry__title' }, entry.href === null
|
|
13
|
+
? entry.title
|
|
14
|
+
: h('a', { class: 'cg-entry__link', href: entry.href }, entry.title)), entry.publishedAt === null
|
|
15
|
+
? null
|
|
16
|
+
: h('time', { class: 'cg-entry__date', datetime: entry.publishedAt }, entry.publishedAt.slice(0, 10)), entry.summary === null ? null : h('p', { class: 'cg-entry__excerpt' }, entry.summary))));
|
|
17
|
+
return h('main', { class: 'cg-main cg-archive', id: 'cg-main' }, input.ancestors.length === 0
|
|
18
|
+
? null
|
|
19
|
+
: h('nav', { class: 'cg-archive__breadcrumb', 'aria-label': input.labels.breadcrumb }, h('ol', {}, ...input.ancestors.map((link) => h('li', {}, h('a', { href: link.href }, link.label))))), h('h1', { class: 'cg-page__title' }, input.term.label), input.children.length === 0
|
|
20
|
+
? null
|
|
21
|
+
: h('ul', { class: 'cg-archive__children', 'aria-label': input.labels.subterms }, ...input.children.map((child) => h('li', {}, h('a', { href: child.href }, child.label)))), items.length === 0
|
|
22
|
+
? h('p', { class: 'cg-collection__empty' }, input.labels.empty)
|
|
23
|
+
: h('ul', { class: 'cg-collection__items' }, ...items), renderPager(input));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Previous/next only — never a numbered pager. This renderer is handed the
|
|
27
|
+
* two hrefs the host resolved and no page-number list, so inventing one here
|
|
28
|
+
* would mean guessing URLs the host never said were valid.
|
|
29
|
+
*/
|
|
30
|
+
function renderPager(input) {
|
|
31
|
+
if (input.page.previousHref === null && input.page.nextHref === null)
|
|
32
|
+
return null;
|
|
33
|
+
return h('nav', { class: 'cg-archive__pager', 'aria-label': input.labels.pagination }, input.page.previousHref === null
|
|
34
|
+
? null
|
|
35
|
+
: h('a', { rel: 'prev', href: input.page.previousHref }, input.labels.previous), input.page.nextHref === null
|
|
36
|
+
? null
|
|
37
|
+
: h('a', { rel: 'next', href: input.page.nextHref }, input.labels.next));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=term-archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"term-archive.js","sourceRoot":"","sources":["../../../src/render/term-archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,165 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Contract D — Thème,
|
|
2
|
+
* Contract D — Thème, `theme@1.0`/`1.1`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Contract B stores a media field as the media library's identifier, never as
|
|
15
|
-
* an URL and never as a rendition (`f.media` in `@cogenta/blocks`). So a
|
|
16
|
-
* reference the theme can hold is that identifier.
|
|
17
|
-
*/
|
|
18
|
-
export type MediaReference = string;
|
|
19
|
-
export interface ImageOptions {
|
|
20
|
-
readonly width?: number;
|
|
21
|
-
readonly height?: number;
|
|
22
|
-
readonly format?: 'avif' | 'webp' | 'jpeg' | 'png';
|
|
23
|
-
readonly fit?: 'cover' | 'contain';
|
|
24
|
-
}
|
|
25
|
-
export interface ImageSource {
|
|
26
|
-
readonly src: string;
|
|
27
|
-
readonly srcset: string;
|
|
28
|
-
readonly width: number;
|
|
29
|
-
readonly height: number;
|
|
30
|
-
/** Alt text and focal point come from the media entity, never invented here. */
|
|
31
|
-
readonly alt: string;
|
|
32
|
-
readonly focal: {
|
|
33
|
-
readonly x: number;
|
|
34
|
-
readonly y: number;
|
|
35
|
-
} | null;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Contract A, "Champs système". A theme only ever sees published entries — the
|
|
39
|
-
* read token carries the `public` role — so `status` is narrow in practice but
|
|
40
|
-
* kept whole here rather than guessed at.
|
|
41
|
-
*
|
|
42
|
-
* The schema-defined fields are open: which of them exist depends on the
|
|
43
|
-
* collection, and a theme must not assume one is present. `entryTitle` in
|
|
44
|
-
* `src/render/entry.ts` is the only place that reaches for one.
|
|
45
|
-
*/
|
|
46
|
-
export interface ContentEntry {
|
|
47
|
-
readonly id: string;
|
|
48
|
-
readonly collection: string;
|
|
49
|
-
readonly locale: string;
|
|
50
|
-
readonly status: 'draft' | 'scheduled' | 'published' | 'archived';
|
|
51
|
-
readonly [field: string]: unknown;
|
|
52
|
-
}
|
|
53
|
-
export interface QueryRequest {
|
|
54
|
-
readonly collection: string;
|
|
55
|
-
readonly filter?: Readonly<Record<string, unknown>>;
|
|
56
|
-
readonly sort?: {
|
|
57
|
-
readonly field: string;
|
|
58
|
-
readonly direction: 'asc' | 'desc';
|
|
59
|
-
};
|
|
60
|
-
readonly limit?: number;
|
|
61
|
-
readonly cursor?: string;
|
|
62
|
-
}
|
|
63
|
-
export interface Page<T> {
|
|
64
|
-
readonly items: readonly T[];
|
|
65
|
-
readonly nextCursor: string | null;
|
|
66
|
-
}
|
|
67
|
-
export interface ContentClient {
|
|
68
|
-
entry(collection: string, id: string): Promise<ContentEntry | null>;
|
|
69
|
-
byPath(path: string): Promise<ContentEntry | null>;
|
|
70
|
-
list(request: QueryRequest): Promise<Page<ContentEntry>>;
|
|
71
|
-
}
|
|
72
|
-
export type LinkTargetInput = {
|
|
73
|
-
collection: string;
|
|
74
|
-
id: string;
|
|
75
|
-
} | {
|
|
76
|
-
path: string;
|
|
77
|
-
} | string;
|
|
78
|
-
export interface RenderContext {
|
|
79
|
-
readonly site: {
|
|
80
|
-
readonly name: string;
|
|
81
|
-
readonly url: string;
|
|
82
|
-
readonly locales: readonly string[];
|
|
83
|
-
readonly defaultLocale: string;
|
|
84
|
-
};
|
|
85
|
-
/** The locale being rendered. */
|
|
86
|
-
readonly locale: string;
|
|
87
|
-
/** The URL being rendered, already resolved. */
|
|
88
|
-
readonly url: URL;
|
|
89
|
-
/** Translation. An unknown key returns the key, never an empty string. */
|
|
90
|
-
t(key: string, values?: Readonly<Record<string, string | number>>): string;
|
|
91
|
-
/** Image variants. Returns what a responsive `<img>` needs, nothing more. */
|
|
92
|
-
image(media: MediaReference, options?: ImageOptions): ImageSource;
|
|
93
|
-
/** URL of an entry, of a path, or of an external target. Locale-aware. */
|
|
94
|
-
link(target: LinkTargetInput): string;
|
|
95
|
-
/** Read-only content access. The only door to data a theme has. */
|
|
96
|
-
readonly content: ContentClient;
|
|
97
|
-
}
|
|
98
|
-
/** Contract D, "Besoins runtime". */
|
|
99
|
-
export type ThemeRuntime = 'static' | 'server' | 'edge';
|
|
100
|
-
export interface ThemeManifest {
|
|
101
|
-
readonly name: string;
|
|
102
|
-
readonly version: string;
|
|
103
|
-
/** Version of the theme contract. */
|
|
104
|
-
readonly engine: string;
|
|
105
|
-
/** Version of the block vocabulary supported. */
|
|
106
|
-
readonly blocks: string;
|
|
107
|
-
/** Every vocabulary block the theme renders. A gap fails installation. */
|
|
108
|
-
readonly implements: readonly string[];
|
|
109
|
-
/** Content types expected, or `'*'`. */
|
|
110
|
-
readonly collections: readonly string[] | '*';
|
|
111
|
-
readonly runtime: ThemeRuntime;
|
|
112
|
-
/** Path to the default skin, relative to the manifest. */
|
|
113
|
-
readonly tokens: string;
|
|
114
|
-
readonly a11y: {
|
|
115
|
-
readonly verified: 'WCAG-2.2-AA' | 'WCAG-2.2-AAA' | 'none';
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Identity function. It exists for the inference and for the single place a
|
|
120
|
-
* manifest is recognised, not to validate: validation happens at installation,
|
|
121
|
-
* on the theme's sources, where a lie can actually be caught.
|
|
122
|
-
*/
|
|
123
|
-
export declare function defineTheme<const M extends ThemeManifest>(manifest: M): M;
|
|
124
|
-
/**
|
|
125
|
-
* Contract D, "Tokens de skin". The set is **closed and complete**: a skin that
|
|
126
|
-
* omits a token is refused. Rendered as `--cogenta-<group>-<name>` into a single
|
|
127
|
-
* stylesheet, so changing skin rewrites one file and needs no build.
|
|
128
|
-
*/
|
|
129
|
-
export interface SkinTokens {
|
|
130
|
-
readonly color: {
|
|
131
|
-
readonly bg: string;
|
|
132
|
-
readonly fg: string;
|
|
133
|
-
readonly accent: string;
|
|
134
|
-
readonly accentFg: string;
|
|
135
|
-
readonly muted: string;
|
|
136
|
-
readonly mutedFg: string;
|
|
137
|
-
readonly border: string;
|
|
138
|
-
};
|
|
139
|
-
readonly font: {
|
|
140
|
-
readonly sans: string;
|
|
141
|
-
readonly serif: string;
|
|
142
|
-
readonly mono: string;
|
|
143
|
-
readonly scale: number;
|
|
144
|
-
readonly baseSize: string;
|
|
145
|
-
};
|
|
146
|
-
readonly space: {
|
|
147
|
-
readonly unit: string;
|
|
148
|
-
readonly density: 'compact' | 'comfortable' | 'spacious';
|
|
149
|
-
};
|
|
150
|
-
readonly radius: {
|
|
151
|
-
readonly sm: string;
|
|
152
|
-
readonly md: string;
|
|
153
|
-
readonly lg: string;
|
|
154
|
-
};
|
|
155
|
-
readonly motion: {
|
|
156
|
-
readonly duration: string;
|
|
157
|
-
readonly easing: string;
|
|
158
|
-
readonly reduced: boolean;
|
|
159
|
-
};
|
|
160
|
-
readonly shadow: {
|
|
161
|
-
readonly sm: string;
|
|
162
|
-
readonly md: string;
|
|
163
|
-
};
|
|
164
|
-
}
|
|
4
|
+
* Re-exported from `@cogenta/theme-kit`, which now holds the one real copy of
|
|
5
|
+
* this contract every theme package (this one included) implements against —
|
|
6
|
+
* see that package's own `contract.ts` for why. This file stays only because
|
|
7
|
+
* `@cogenta/theme-canonical`'s own public surface (`index.ts`'s
|
|
8
|
+
* `export * from './theme-contract.js'`) has always named these symbols, and
|
|
9
|
+
* a theme installed from this package before today must keep resolving them
|
|
10
|
+
* from the same place.
|
|
11
|
+
*/
|
|
12
|
+
export { type ContentClient, type ContentEntry, defineTheme, type ImageOptions, type ImageSource, type LinkTargetInput, type MediaReference, type Page, type QueryRequest, type RenderContext, type SkinTokens, type ThemeManifest, type ThemeRuntime, } from '@cogenta/theme-kit';
|
|
165
13
|
//# sourceMappingURL=theme-contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-contract.d.ts","sourceRoot":"","sources":["../../src/theme-contract.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"theme-contract.d.ts","sourceRoot":"","sources":["../../src/theme-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,IAAI,EACT,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAA"}
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Contract D — Thème,
|
|
2
|
+
* Contract D — Thème, `theme@1.0`/`1.1`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* that matches what is already frozen elsewhere; both are flagged in the code.
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Identity function. It exists for the inference and for the single place a
|
|
15
|
-
* manifest is recognised, not to validate: validation happens at installation,
|
|
16
|
-
* on the theme's sources, where a lie can actually be caught.
|
|
4
|
+
* Re-exported from `@cogenta/theme-kit`, which now holds the one real copy of
|
|
5
|
+
* this contract every theme package (this one included) implements against —
|
|
6
|
+
* see that package's own `contract.ts` for why. This file stays only because
|
|
7
|
+
* `@cogenta/theme-canonical`'s own public surface (`index.ts`'s
|
|
8
|
+
* `export * from './theme-contract.js'`) has always named these symbols, and
|
|
9
|
+
* a theme installed from this package before today must keep resolving them
|
|
10
|
+
* from the same place.
|
|
17
11
|
*/
|
|
18
|
-
export
|
|
19
|
-
return manifest;
|
|
20
|
-
}
|
|
12
|
+
export { defineTheme, } from '@cogenta/theme-kit';
|
|
21
13
|
//# sourceMappingURL=theme-contract.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-contract.js","sourceRoot":"","sources":["../../src/theme-contract.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"theme-contract.js","sourceRoot":"","sources":["../../src/theme-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAGL,WAAW,GAWZ,MAAM,oBAAoB,CAAA"}
|
package/dist/theme.config.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Contract D — Thème, `theme@1.0`.
|
|
3
3
|
*
|
|
4
|
-
* `implements` lists the
|
|
5
|
-
* lists them. A theme that omits one fails
|
|
6
|
-
* guarantees that switching theme never erases
|
|
4
|
+
* `implements` lists the seventeen blocks of contract B (`blocks@2.0`, RFC
|
|
5
|
+
* 0001) in the order the contract lists them. A theme that omits one fails
|
|
6
|
+
* installation, which is what guarantees that switching theme never erases
|
|
7
|
+
* content.
|
|
7
8
|
*
|
|
8
9
|
* `runtime: 'static'` describes what *this theme* needs, not what every block
|
|
9
10
|
* on a page needs: `collectionList` is `runtime: 'server'` in the vocabulary
|
|
@@ -14,18 +15,6 @@
|
|
|
14
15
|
* `a11y.verified` is a claim this package has to keep true: the tests assert
|
|
15
16
|
* the heading outline, the mandatory `alt`, and the closed token set.
|
|
16
17
|
*/
|
|
17
|
-
declare const _default:
|
|
18
|
-
readonly name: "canonical";
|
|
19
|
-
readonly version: "1.0.0";
|
|
20
|
-
readonly engine: "^1.0.0";
|
|
21
|
-
readonly blocks: "^1.0.0";
|
|
22
|
-
readonly implements: readonly ["hero", "prose", "mediaFigure", "featureGrid", "cta", "gallery", "quote", "faq", "stats", "logos", "collectionList", "embed"];
|
|
23
|
-
readonly collections: readonly ["article", "page"];
|
|
24
|
-
readonly runtime: "static";
|
|
25
|
-
readonly tokens: "./tokens.json";
|
|
26
|
-
readonly a11y: {
|
|
27
|
-
readonly verified: "WCAG-2.2-AA";
|
|
28
|
-
};
|
|
29
|
-
};
|
|
18
|
+
declare const _default: import("./src/theme-contract.js").ThemeManifest;
|
|
30
19
|
export default _default;
|
|
31
20
|
//# sourceMappingURL=theme.config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.config.d.ts","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"theme.config.d.ts","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG"}
|
package/dist/theme.config.js
CHANGED
|
@@ -2,9 +2,10 @@ import { defineTheme } from './src/theme-contract.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Contract D — Thème, `theme@1.0`.
|
|
4
4
|
*
|
|
5
|
-
* `implements` lists the
|
|
6
|
-
* lists them. A theme that omits one fails
|
|
7
|
-
* guarantees that switching theme never erases
|
|
5
|
+
* `implements` lists the seventeen blocks of contract B (`blocks@2.0`, RFC
|
|
6
|
+
* 0001) in the order the contract lists them. A theme that omits one fails
|
|
7
|
+
* installation, which is what guarantees that switching theme never erases
|
|
8
|
+
* content.
|
|
8
9
|
*
|
|
9
10
|
* `runtime: 'static'` describes what *this theme* needs, not what every block
|
|
10
11
|
* on a page needs: `collectionList` is `runtime: 'server'` in the vocabulary
|
|
@@ -17,9 +18,14 @@ import { defineTheme } from './src/theme-contract.js';
|
|
|
17
18
|
*/
|
|
18
19
|
export default defineTheme({
|
|
19
20
|
name: 'canonical',
|
|
20
|
-
|
|
21
|
+
// Minor: the theme gained the five new blocks of `blocks@2.0` without any
|
|
22
|
+
// change to how it renders the twelve it already implemented — nothing a
|
|
23
|
+
// site authored before this stops rendering identically.
|
|
24
|
+
version: '1.1.0',
|
|
25
|
+
description: 'The reference theme: all seventeen blocks, zero client JavaScript, a neutral, accessible default.',
|
|
26
|
+
author: 'Cogenta',
|
|
21
27
|
engine: '^1.0.0',
|
|
22
|
-
blocks: '^
|
|
28
|
+
blocks: '^2.0.0',
|
|
23
29
|
implements: [
|
|
24
30
|
'hero',
|
|
25
31
|
'prose',
|
|
@@ -33,6 +39,11 @@ export default defineTheme({
|
|
|
33
39
|
'logos',
|
|
34
40
|
'collectionList',
|
|
35
41
|
'embed',
|
|
42
|
+
'testimonial',
|
|
43
|
+
'pricingTable',
|
|
44
|
+
'accordion',
|
|
45
|
+
'statCounter',
|
|
46
|
+
'logoStrip',
|
|
36
47
|
],
|
|
37
48
|
collections: ['article', 'page'],
|
|
38
49
|
runtime: 'static',
|
package/dist/theme.config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.config.js","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD
|
|
1
|
+
{"version":3,"file":"theme.config.js","sourceRoot":"","sources":["../theme.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAErD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAe,WAAW,CAAC;IACzB,IAAI,EAAE,WAAW;IACjB,0EAA0E;IAC1E,yEAAyE;IACzE,yDAAyD;IACzD,OAAO,EAAE,OAAO;IAChB,WAAW,EACT,mGAAmG;IACrG,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,SAAS,EAAE,MAAM,CAAC;IAChC,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;CAClC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogenta/theme-canonical",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "The reference Cogenta theme: the twelve vocabulary blocks, rendered accessibly, with zero client JavaScript.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,9 @@
|
|
|
39
39
|
"directory": "packages/theme-canonical"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@cogenta/blocks": "0.1
|
|
42
|
+
"@cogenta/blocks": "1.0.1",
|
|
43
|
+
"@cogenta/render": "0.2.1",
|
|
44
|
+
"@cogenta/theme-kit": "0.3.0"
|
|
43
45
|
},
|
|
44
46
|
"peerDependencies": {
|
|
45
47
|
"astro": "^7.2.1"
|
package/src/index.ts
CHANGED
|
@@ -11,10 +11,14 @@ export * from './render/blocks/media-figure.js'
|
|
|
11
11
|
export * from './render/blocks/prose.js'
|
|
12
12
|
export * from './render/blocks/quote.js'
|
|
13
13
|
export * from './render/blocks/stats.js'
|
|
14
|
+
export * from './render/chrome.js'
|
|
15
|
+
export * from './render/comments.js'
|
|
14
16
|
export * from './render/entry.js'
|
|
15
17
|
export * from './render/heading.js'
|
|
16
18
|
export * from './render/html.js'
|
|
19
|
+
export * from './render/icons.js'
|
|
17
20
|
export * from './render/media.js'
|
|
18
21
|
export * from './render/render-block.js'
|
|
19
22
|
export * from './render/rich-text.js'
|
|
23
|
+
export * from './render/term-archive.js'
|
|
20
24
|
export * from './theme-contract.js'
|
package/src/render/actions.ts
CHANGED
|
@@ -1,57 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { type HtmlElement, h } from './html.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A target is resolved through `ctx.link` in every case, including an external
|
|
7
|
-
* `href`: the context is the only thing that knows the locale prefix and the
|
|
8
|
-
* site's base URL, and duplicating that reasoning here is how a theme starts
|
|
9
|
-
* emitting broken links in a sub-path deployment.
|
|
10
|
-
*/
|
|
11
|
-
export function href(ctx: RenderContext, target: LinkTarget): string {
|
|
12
|
-
return 'href' in target ? ctx.link(target.href) : ctx.link(target)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** A link that leaves the site gets the protection; a same-site one must not. */
|
|
16
|
-
function isExternal(ctx: RenderContext, url: string): boolean {
|
|
17
|
-
if (!/^[a-z][a-z0-9+.-]*:/i.test(url)) return false
|
|
18
|
-
const site = URL.parse(ctx.site.url)
|
|
19
|
-
const target = URL.parse(url)
|
|
20
|
-
if (site === null || target === null) return false
|
|
21
|
-
return site.host !== target.host
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function actionLink(ctx: RenderContext, action: Action): HtmlElement {
|
|
25
|
-
const url = href(ctx, action.target)
|
|
26
|
-
const external = isExternal(ctx, url)
|
|
27
|
-
return h(
|
|
28
|
-
'a',
|
|
29
|
-
{
|
|
30
|
-
class: 'cg-action',
|
|
31
|
-
// `emphasis` is a semantic intent, so it stays an attribute the skin reads
|
|
32
|
-
// rather than a class the block dictated. Default `secondary`: promoting
|
|
33
|
-
// an unstated action to primary is a decision the editor did not make.
|
|
34
|
-
'data-emphasis': action.emphasis ?? 'secondary',
|
|
35
|
-
href: url,
|
|
36
|
-
rel: external ? 'noopener noreferrer' : undefined,
|
|
37
|
-
},
|
|
38
|
-
action.label,
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* A list, not a row of loose anchors: a screen reader then announces "list, 2
|
|
44
|
-
* items" and the actions are navigable as a group.
|
|
45
|
-
*/
|
|
46
|
-
export function actionList(
|
|
47
|
-
ctx: RenderContext,
|
|
48
|
-
actions: readonly Action[] | undefined,
|
|
49
|
-
label: string,
|
|
50
|
-
): HtmlElement | null {
|
|
51
|
-
if (actions === undefined || actions.length === 0) return null
|
|
52
|
-
return h(
|
|
53
|
-
'ul',
|
|
54
|
-
{ class: 'cg-actions', 'aria-label': label },
|
|
55
|
-
actions.map((action) => h('li', {}, actionLink(ctx, action))),
|
|
56
|
-
)
|
|
57
|
-
}
|
|
1
|
+
/** Re-exported from `@cogenta/theme-kit` — see that package's `actions.ts`. */
|
|
2
|
+
export { actionLink, actionList, href } from '@cogenta/theme-kit'
|