@hraness/design-kit 0.38.0 → 0.39.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/MARKETING_COPY.md +2 -0
- package/README.md +33 -8
- package/dist/{chunk-13bq7myc.js → chunk-1dgm85ta.js} +191 -55
- package/dist/chunk-6mx403v5.js +286 -0
- package/dist/{chunk-s222cmt9.js → chunk-dc8v05zh.js} +6 -137
- package/dist/{chunk-kz59614q.js → chunk-fcs5qekr.js} +1 -1
- package/dist/{chunk-z974c20s.js → chunk-fxwed3e5.js} +1 -1
- package/dist/{chunk-san9drwt.js → chunk-vy0pt84a.js} +1 -1
- package/dist/{chunk-gpsekwkj.js → chunk-w1y1m3m7.js} +274 -1
- package/dist/index.js +24 -12
- package/dist/mockups/client.js +3 -3
- package/dist/mockups/index.js +3 -3
- package/dist/provider-marks.js +1 -1
- package/dist/react/index.js +40 -7
- package/dist/react/server.js +5 -3
- package/dist/stylex-manifest.json +1 -1
- package/package.json +8 -4
- package/portfolio-inventory.json +1 -1
- package/src/compiler-foundation.css +1 -0
- package/src/index.ts +1 -0
- package/src/marketing-marquee.css +281 -0
- package/src/marketing-marquee.ts +206 -0
- package/src/provider-marks.generated.ts +84 -0
- package/src/provider-marks.ts +27 -4
- package/src/react/design-gallery.tsx +19 -0
- package/src/react/index.ts +1 -0
- package/src/react/marketing-marquee.tsx +71 -0
- package/src/react/server.ts +1 -0
- package/src/styles.css +1 -0
- package/vendor/provider-marks/UPSTREAM.md +14 -0
- package/vendor/provider-marks/bootstrap-icons/calendar-event-fill.svg +3 -0
- package/vendor/provider-marks/bootstrap-icons/filetype-csv.svg +3 -0
- package/vendor/provider-marks/bootstrap-icons/globe2.svg +3 -0
- package/vendor/provider-marks/bootstrap-icons/microsoft.svg +3 -0
- package/vendor/provider-marks/bootstrap-icons/person-vcard-fill.svg +3 -0
- package/vendor/provider-marks/bootstrap-icons/shop.svg +3 -0
- package/vendor/provider-marks/simple-icons/bluesky.svg +1 -0
- package/vendor/provider-marks/simple-icons/facebook.svg +1 -0
- package/vendor/provider-marks/simple-icons/github.svg +1 -0
- package/vendor/provider-marks/simple-icons/gmail.svg +1 -0
- package/vendor/provider-marks/simple-icons/google.svg +1 -0
- package/vendor/provider-marks/simple-icons/instagram.svg +1 -0
- package/vendor/provider-marks/simple-icons/reddit.svg +1 -0
- package/vendor/provider-marks/simple-icons/substack.svg +1 -0
- package/vendor/provider-marks/simple-icons/telegram.svg +1 -0
- package/vendor/provider-marks/simple-icons/threads.svg +1 -0
- package/vendor/provider-marks/simple-icons/tiktok.svg +1 -0
- package/vendor/provider-marks/simple-icons/twitch.svg +1 -0
- package/vendor/provider-marks/simple-icons/x.svg +1 -0
- package/vendor/provider-marks/simple-icons/ycombinator.svg +1 -0
- package/vendor/provider-marks/simple-icons/youtube.svg +1 -0
- package/dist/chunk-gmea6p0d.js +0 -13
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ARTICLE_BYLINE_PREFIX,
|
|
3
|
+
ARTICLE_SOURCES_HEADING,
|
|
4
|
+
ARTICLE_TOC_LABEL,
|
|
5
|
+
articleProvenanceSentence,
|
|
6
|
+
assertArticleAuthor,
|
|
7
|
+
assertArticleCalloutTone,
|
|
8
|
+
assertArticleDates,
|
|
9
|
+
assertArticleHref,
|
|
10
|
+
formatArticleDate
|
|
11
|
+
} from "./chunk-77391vmq.js";
|
|
12
|
+
import {
|
|
13
|
+
providerMark,
|
|
14
|
+
providerMarkMonogram
|
|
15
|
+
} from "./chunk-w1y1m3m7.js";
|
|
16
|
+
|
|
17
|
+
// src/article-html.ts
|
|
18
|
+
var ROOT_CLASS = "plain-site plain-publication plain-publication--embedded";
|
|
19
|
+
var SEPARATOR = '<span aria-hidden="true"> · </span>';
|
|
20
|
+
var ESCAPES = {
|
|
21
|
+
'"': """,
|
|
22
|
+
"&": "&",
|
|
23
|
+
"'": "'",
|
|
24
|
+
"<": "<",
|
|
25
|
+
">": ">"
|
|
26
|
+
};
|
|
27
|
+
function escapeArticleHtml(value) {
|
|
28
|
+
return value.replace(/["&'<>]/gu, (character) => ESCAPES[character] ?? character);
|
|
29
|
+
}
|
|
30
|
+
function classes(...values) {
|
|
31
|
+
return values.filter((value) => value !== undefined && value !== "").join(" ");
|
|
32
|
+
}
|
|
33
|
+
function dateHtml(label, value) {
|
|
34
|
+
return `${label} <time dateTime="${escapeArticleHtml(value)}">${escapeArticleHtml(formatArticleDate(value))}</time>`;
|
|
35
|
+
}
|
|
36
|
+
function present(value) {
|
|
37
|
+
return value !== undefined && value !== "";
|
|
38
|
+
}
|
|
39
|
+
function renderArticleBylineHtml(author) {
|
|
40
|
+
assertArticleAuthor(author);
|
|
41
|
+
const name = escapeArticleHtml(author.name);
|
|
42
|
+
const linked = author.href === undefined ? name : `<a href="${escapeArticleHtml(author.href)}" rel="author">${name}</a>`;
|
|
43
|
+
return `<span class="plain-publication__byline" data-author-kind="${author.kind}">${ARTICLE_BYLINE_PREFIX} ${linked}</span>`;
|
|
44
|
+
}
|
|
45
|
+
function renderArticleProvenanceHtml(provenance) {
|
|
46
|
+
const sentence = articleProvenanceSentence(provenance);
|
|
47
|
+
return `<p class="plain-publication__provenance" data-drafting="${escapeArticleHtml(provenance.drafting)}" data-reviewer-type="${escapeArticleHtml(provenance.review?.reviewerType ?? "none")}">${escapeArticleHtml(sentence)}</p>`;
|
|
48
|
+
}
|
|
49
|
+
function renderArticleHtml(input) {
|
|
50
|
+
const headingId = input.headingId ?? "article-title";
|
|
51
|
+
const {
|
|
52
|
+
published,
|
|
53
|
+
updated,
|
|
54
|
+
showDates = true
|
|
55
|
+
} = input;
|
|
56
|
+
assertArticleDates(updated === undefined ? {
|
|
57
|
+
published
|
|
58
|
+
} : {
|
|
59
|
+
published,
|
|
60
|
+
updated
|
|
61
|
+
});
|
|
62
|
+
const toc = input.toc ?? [];
|
|
63
|
+
for (const item of toc) {
|
|
64
|
+
if (!item.href.startsWith("#") || item.href.length < 2)
|
|
65
|
+
throw new RangeError("Contents links must point to a heading in this article.");
|
|
66
|
+
}
|
|
67
|
+
const tocId = `${headingId}-contents`;
|
|
68
|
+
const meta = [input.author === undefined ? "" : renderArticleBylineHtml(input.author), showDates ? dateHtml("Published", published) : "", showDates && updated !== undefined ? dateHtml("Updated", updated) : ""].filter(Boolean).join(SEPARATOR);
|
|
69
|
+
const header = ['<header class="plain-publication__article-header">', present(input.eyebrow) ? `<p class="plain-publication__eyebrow">${escapeArticleHtml(input.eyebrow)}</p>` : "", `<h1 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(input.heading)}</h1>`, present(input.dek) ? `<p class="plain-publication__article-dek">${escapeArticleHtml(input.dek)}</p>` : "", meta === "" ? "" : `<p class="plain-publication__article-meta">${meta}</p>`, input.provenance === null ? "" : renderArticleProvenanceHtml(input.provenance), "</header>"].join("");
|
|
70
|
+
const nav = toc.length === 0 ? "" : [`<nav aria-labelledby="${escapeArticleHtml(tocId)}" class="plain-publication__toc">`, `<p id="${escapeArticleHtml(tocId)}">${escapeArticleHtml(input.tocLabel ?? ARTICLE_TOC_LABEL)}</p>`, "<ol>", ...toc.map((item) => `<li><a href="${escapeArticleHtml(item.href)}">${escapeArticleHtml(item.label)}</a></li>`), "</ol></nav>"].join("");
|
|
71
|
+
return [`<article aria-labelledby="${escapeArticleHtml(headingId)}" class="${escapeArticleHtml(classes(ROOT_CLASS, "plain-publication__article", input.className))}" data-hraness-article="" data-toc="${toc.length > 0 ? "aside" : "none"}"${input.id === undefined ? "" : ` id="${escapeArticleHtml(input.id)}"`}>`, header, '<div class="plain-publication__article-layout">', nav, `<div class="plain-publication__article-body">${input.bodyHtml}</div>`, "</div>", present(input.afterHtml) ? `<footer class="plain-publication__article-footer">${input.afterHtml}</footer>` : "", "</article>"].join("");
|
|
72
|
+
}
|
|
73
|
+
function renderArticleSourcesHtml({
|
|
74
|
+
heading = ARTICLE_SOURCES_HEADING,
|
|
75
|
+
headingId = "article-sources",
|
|
76
|
+
showDates = true,
|
|
77
|
+
sources
|
|
78
|
+
}) {
|
|
79
|
+
if (sources.length === 0)
|
|
80
|
+
return "";
|
|
81
|
+
for (const source of sources) {
|
|
82
|
+
assertArticleHref(source.href);
|
|
83
|
+
formatArticleDate(source.checkedOn);
|
|
84
|
+
}
|
|
85
|
+
return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="plain-publication__sources">`, `<h2 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</h2>`, "<ol>", ...sources.map((source) => {
|
|
86
|
+
const meta = [present(source.publisher) ? escapeArticleHtml(source.publisher) : "", showDates ? dateHtml("Checked", source.checkedOn) : ""].filter(Boolean).join(SEPARATOR);
|
|
87
|
+
return [`<li><a href="${escapeArticleHtml(source.href)}">${escapeArticleHtml(source.title)}</a>`, meta === "" ? "" : `<span>${meta}</span>`, "</li>"].join("");
|
|
88
|
+
}), "</ol></section>"].join("");
|
|
89
|
+
}
|
|
90
|
+
function renderArticleCalloutHtml(input) {
|
|
91
|
+
const tone = input.tone ?? "note";
|
|
92
|
+
assertArticleCalloutTone(tone);
|
|
93
|
+
const body = input.text === undefined ? input.bodyHtml : `<p>${escapeArticleHtml(input.text)}</p>`;
|
|
94
|
+
return `<div class="plain-publication__callout" data-tone="${tone}" role="note">${present(input.label) ? `<strong>${escapeArticleHtml(input.label)}</strong>` : ""}${body}</div>`;
|
|
95
|
+
}
|
|
96
|
+
function assertArticleMark(mark) {
|
|
97
|
+
if (!mark.startsWith("data:image/svg+xml,"))
|
|
98
|
+
assertArticleHref(mark);
|
|
99
|
+
}
|
|
100
|
+
function renderArticleRelatedHtml({
|
|
101
|
+
heading = "Related products",
|
|
102
|
+
headingId = "article-related-products",
|
|
103
|
+
items
|
|
104
|
+
}) {
|
|
105
|
+
if (items.length === 0)
|
|
106
|
+
return "";
|
|
107
|
+
for (const item of items) {
|
|
108
|
+
assertArticleHref(item.href);
|
|
109
|
+
if (present(item.mark))
|
|
110
|
+
assertArticleMark(item.mark);
|
|
111
|
+
}
|
|
112
|
+
return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="plain-publication__related">`, `<div class="plain-publication__section-heading"><h2 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</h2></div>`, '<div class="plain-publication__related-grid">', ...items.map((item) => [`<a href="${escapeArticleHtml(item.href)}">`, present(item.mark) ? `<img alt="" class="plain-publication__related-mark" decoding="async" height="44" src="${escapeArticleHtml(item.mark)}" width="44">` : "", `<span class="plain-publication__related-text"><strong>${escapeArticleHtml(item.name)}</strong>`, `<span>${escapeArticleHtml(item.role ?? item.relationship)}</span></span></a>`].join("")), "</div></section>"].join("");
|
|
113
|
+
}
|
|
114
|
+
function renderArticleIndexHtml({
|
|
115
|
+
className,
|
|
116
|
+
heading,
|
|
117
|
+
headingId,
|
|
118
|
+
headingLevel = 2,
|
|
119
|
+
id,
|
|
120
|
+
items,
|
|
121
|
+
showDates = true,
|
|
122
|
+
summary
|
|
123
|
+
}) {
|
|
124
|
+
if (![1, 2, 3, 4, 5].includes(headingLevel))
|
|
125
|
+
throw new RangeError("Article index heading level must be 1 to 5.");
|
|
126
|
+
const hrefs = new Set;
|
|
127
|
+
for (const item of items) {
|
|
128
|
+
assertArticleHref(item.href);
|
|
129
|
+
assertArticleDates(item.updated === undefined ? {
|
|
130
|
+
published: item.published
|
|
131
|
+
} : {
|
|
132
|
+
published: item.published,
|
|
133
|
+
updated: item.updated
|
|
134
|
+
});
|
|
135
|
+
if (hrefs.has(item.href))
|
|
136
|
+
throw new RangeError(`Article index lists ${item.href} more than once.`);
|
|
137
|
+
hrefs.add(item.href);
|
|
138
|
+
}
|
|
139
|
+
const heading1 = `h${headingLevel}`;
|
|
140
|
+
const entry = `h${headingLevel + 1}`;
|
|
141
|
+
return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="${escapeArticleHtml(classes(ROOT_CLASS, "plain-publication__list", className))}" data-hraness-article-index=""${id === undefined ? "" : ` id="${escapeArticleHtml(id)}"`}>`, `<div class="plain-publication__section-heading"><${heading1} id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</${heading1}>`, present(summary) ? `<p>${escapeArticleHtml(summary)}</p>` : "", "</div>", '<div class="plain-publication__article-list">', ...items.map((item) => ['<article class="plain-publication__entry">', present(item.eyebrow) ? `<p class="plain-publication__entry-label">${escapeArticleHtml(item.eyebrow)}</p>` : "", `<${entry} class="plain-publication__entry-title"><a href="${escapeArticleHtml(item.href)}">${escapeArticleHtml(item.title)}</a></${entry}>`, `<p class="plain-publication__entry-dek">${escapeArticleHtml(item.dek)}</p>`, showDates ? ['<p class="plain-publication__entry-meta">', dateHtml("Published", item.published), item.updated === undefined ? "" : SEPARATOR + dateHtml("Updated", item.updated), "</p>"].join("") : "", "</article>"].join("")), "</div></section>"].join("");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/marketing-marquee.ts
|
|
145
|
+
var MARKETING_MARQUEE_COUNT_TOKEN = "{count}";
|
|
146
|
+
var MARKETING_MARQUEE_MAX_ITEMS = 64;
|
|
147
|
+
var MARKETING_MARQUEE_DEFAULT_PAUSE_LABEL = "Pause scrolling";
|
|
148
|
+
var MIN_LOOP_ITEMS = 20;
|
|
149
|
+
var MAX_NAME_LENGTH = 64;
|
|
150
|
+
var MAX_LABEL_LENGTH = 120;
|
|
151
|
+
var ID_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/u;
|
|
152
|
+
var FORBIDDEN_ARTWORK = /<script|<foreignObject|on[a-z]+\s*=|javascript:/iu;
|
|
153
|
+
var ROOT_CLASS2 = "hraness-marketing-marquee";
|
|
154
|
+
var MARKETING_MARQUEE_CONTROL_ICONS = {
|
|
155
|
+
pause: "M5 3.25a1 1 0 0 1 1 1v7.5a1 1 0 0 1-2 0v-7.5a1 1 0 0 1 1-1Zm6 0a1 1 0 0 1 1 1v7.5a1 1 0 0 1-2 0v-7.5a1 1 0 0 1 1-1Z",
|
|
156
|
+
play: "M5.25 3.6v8.8a.75.75 0 0 0 1.14.64l7.04-4.4a.75.75 0 0 0 0-1.28L6.39 2.96a.75.75 0 0 0-1.14.64Z"
|
|
157
|
+
};
|
|
158
|
+
function requireText(value, field, limit) {
|
|
159
|
+
const text = value.trim();
|
|
160
|
+
if (text === "")
|
|
161
|
+
throw new RangeError(`Marketing marquee ${field} must not be empty.`);
|
|
162
|
+
if (text.length > limit)
|
|
163
|
+
throw new RangeError(`Marketing marquee ${field} must be at most ${limit} characters.`);
|
|
164
|
+
return text;
|
|
165
|
+
}
|
|
166
|
+
function resolveMark(mark, name) {
|
|
167
|
+
if (mark === undefined)
|
|
168
|
+
return providerMark(name);
|
|
169
|
+
if (typeof mark === "string")
|
|
170
|
+
return providerMark(mark);
|
|
171
|
+
return mark;
|
|
172
|
+
}
|
|
173
|
+
function resolveMarketingMarquee(input) {
|
|
174
|
+
if (!ID_PATTERN.test(input.id))
|
|
175
|
+
throw new RangeError("Marketing marquee id must start with a letter and use at most 64 letters, digits, hyphens, or underscores.");
|
|
176
|
+
const label = requireText(input.label, "label", MAX_LABEL_LENGTH);
|
|
177
|
+
const parts = label.split(MARKETING_MARQUEE_COUNT_TOKEN);
|
|
178
|
+
if (parts.length !== 2)
|
|
179
|
+
throw new RangeError(`Marketing marquee label must contain ${MARKETING_MARQUEE_COUNT_TOKEN} exactly once.`);
|
|
180
|
+
if (input.items.length === 0)
|
|
181
|
+
throw new RangeError("Marketing marquee needs at least one item.");
|
|
182
|
+
if (input.items.length > MARKETING_MARQUEE_MAX_ITEMS)
|
|
183
|
+
throw new RangeError(`Marketing marquee shows at most ${MARKETING_MARQUEE_MAX_ITEMS} items.`);
|
|
184
|
+
if (input.align !== undefined && input.align !== "start" && input.align !== "center")
|
|
185
|
+
throw new RangeError("Marketing marquee align must be start or center.");
|
|
186
|
+
const names = new Set;
|
|
187
|
+
const symbols = [];
|
|
188
|
+
const symbolIds = new Map;
|
|
189
|
+
const items = input.items.map((item) => {
|
|
190
|
+
const name = requireText(item.name, "item name", MAX_NAME_LENGTH);
|
|
191
|
+
if (names.has(name))
|
|
192
|
+
throw new RangeError(`Marketing marquee lists ${JSON.stringify(name)} more than once.`);
|
|
193
|
+
names.add(name);
|
|
194
|
+
const descriptor = resolveMark(item.mark, name);
|
|
195
|
+
if (descriptor === undefined || descriptor.glyph.body === "") {
|
|
196
|
+
return {
|
|
197
|
+
name,
|
|
198
|
+
mark: {
|
|
199
|
+
kind: "monogram",
|
|
200
|
+
monogram: descriptor?.monogram ?? providerMarkMonogram(name)
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const {
|
|
205
|
+
viewBox,
|
|
206
|
+
body
|
|
207
|
+
} = descriptor.glyph;
|
|
208
|
+
if (FORBIDDEN_ARTWORK.test(body) || /["<>]/u.test(viewBox))
|
|
209
|
+
throw new RangeError(`Marketing marquee artwork for ${JSON.stringify(name)} contains unsupported markup.`);
|
|
210
|
+
const key = `${viewBox}
|
|
211
|
+
${body}`;
|
|
212
|
+
let symbolId = symbolIds.get(key);
|
|
213
|
+
if (symbolId === undefined) {
|
|
214
|
+
symbolId = `${input.id}-mark-${symbols.length}`;
|
|
215
|
+
symbolIds.set(key, symbolId);
|
|
216
|
+
symbols.push({
|
|
217
|
+
body,
|
|
218
|
+
id: symbolId,
|
|
219
|
+
viewBox
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
name,
|
|
224
|
+
mark: {
|
|
225
|
+
kind: "glyph",
|
|
226
|
+
symbolId
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
let action = null;
|
|
231
|
+
if (input.action !== undefined) {
|
|
232
|
+
assertArticleHref(input.action.href);
|
|
233
|
+
action = {
|
|
234
|
+
href: input.action.href,
|
|
235
|
+
label: requireText(input.action.label, "action label", MAX_LABEL_LENGTH)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
action,
|
|
240
|
+
align: input.align ?? "start",
|
|
241
|
+
className: [ROOT_CLASS2, input.className?.trim()].filter(Boolean).join(" "),
|
|
242
|
+
copies: Math.max(2, 1 + Math.ceil(MIN_LOOP_ITEMS / items.length)),
|
|
243
|
+
id: input.id,
|
|
244
|
+
items,
|
|
245
|
+
label: {
|
|
246
|
+
after: parts[1] ?? "",
|
|
247
|
+
before: parts[0] ?? "",
|
|
248
|
+
count: String(items.length)
|
|
249
|
+
},
|
|
250
|
+
labelId: `${input.id}-label`,
|
|
251
|
+
pauseLabel: requireText(input.pauseLabel ?? MARKETING_MARQUEE_DEFAULT_PAUSE_LABEL, "pause label", MAX_LABEL_LENGTH),
|
|
252
|
+
symbols,
|
|
253
|
+
toggleId: `${input.id}-pause`
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function itemHtml(item) {
|
|
257
|
+
const mark = item.mark.kind === "glyph" ? `<svg aria-hidden="true" class="${ROOT_CLASS2}__mark" fill="currentColor" focusable="false" height="20" width="20"><use href="#${item.mark.symbolId}"></use></svg>` : `<span aria-hidden="true" class="${ROOT_CLASS2}__monogram">${escapeArticleHtml(item.mark.monogram)}</span>`;
|
|
258
|
+
return `<li class="${ROOT_CLASS2}__item">${mark}<span class="${ROOT_CLASS2}__name">${escapeArticleHtml(item.name)}</span></li>`;
|
|
259
|
+
}
|
|
260
|
+
function controlIconHtml(icon) {
|
|
261
|
+
return `<svg aria-hidden="true" class="${ROOT_CLASS2}__control-icon" data-icon="${icon}" fill="currentColor" focusable="false" height="16" viewBox="0 0 16 16" width="16"><path d="${MARKETING_MARQUEE_CONTROL_ICONS[icon]}"></path></svg>`;
|
|
262
|
+
}
|
|
263
|
+
function renderMarketingMarqueeHtml(input) {
|
|
264
|
+
const marquee = resolveMarketingMarquee(input);
|
|
265
|
+
const items = marquee.items.map(itemHtml).join("");
|
|
266
|
+
const lists = Array.from({
|
|
267
|
+
length: marquee.copies
|
|
268
|
+
}, (_, index) => `<ul${index === 0 ? "" : ' aria-hidden="true"'} class="${ROOT_CLASS2}__list">${items}</ul>`).join("");
|
|
269
|
+
const sprite = marquee.symbols.length === 0 ? "" : `<svg aria-hidden="true" class="${ROOT_CLASS2}__sprite" focusable="false" height="0" width="0">${marquee.symbols.map((symbol) => `<symbol id="${symbol.id}" viewBox="${symbol.viewBox}">${symbol.body}</symbol>`).join("")}</svg>`;
|
|
270
|
+
const action = marquee.action === null ? "" : `<a class="${ROOT_CLASS2}__action hraness-text-link" href="${escapeArticleHtml(marquee.action.href)}">${escapeArticleHtml(marquee.action.label)}</a>`;
|
|
271
|
+
return [`<section aria-labelledby="${marquee.labelId}" class="${escapeArticleHtml(marquee.className)}" data-align="${marquee.align}" data-hraness-marketing="marquee" id="${marquee.id}">`, sprite, `<div class="${ROOT_CLASS2}__header">`, `<p class="${ROOT_CLASS2}__label" id="${marquee.labelId}">${escapeArticleHtml(marquee.label.before)}<strong class="${ROOT_CLASS2}__count">${marquee.label.count}</strong>${escapeArticleHtml(marquee.label.after)}</p>`, action, "</div>", `<input class="${ROOT_CLASS2}__toggle" id="${marquee.toggleId}" type="checkbox"/>`, `<div class="${ROOT_CLASS2}__viewport"><div class="${ROOT_CLASS2}__track">${lists}</div></div>`, `<label class="${ROOT_CLASS2}__control" for="${marquee.toggleId}"><span class="${ROOT_CLASS2}__control-text">${escapeArticleHtml(marquee.pauseLabel)}</span>${controlIconHtml("pause")}${controlIconHtml("play")}</label>`, "</section>"].join("");
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/diagrams.ts
|
|
275
|
+
var diagramMetrics = Object.freeze({
|
|
276
|
+
labelSize: 20,
|
|
277
|
+
detailSize: 16,
|
|
278
|
+
strokeWidth: 1.5,
|
|
279
|
+
arrowheadSize: 6,
|
|
280
|
+
nodePadding: 24,
|
|
281
|
+
nodeGap: 48,
|
|
282
|
+
minimumCanvasWidth: 640,
|
|
283
|
+
fontFamily: '"Nebula Sans", ui-sans-serif, system-ui, sans-serif'
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
export { escapeArticleHtml, renderArticleBylineHtml, renderArticleProvenanceHtml, renderArticleHtml, renderArticleSourcesHtml, renderArticleCalloutHtml, renderArticleRelatedHtml, renderArticleIndexHtml, MARKETING_MARQUEE_COUNT_TOKEN, MARKETING_MARQUEE_MAX_ITEMS, MARKETING_MARQUEE_DEFAULT_PAUSE_LABEL, MARKETING_MARQUEE_CONTROL_ICONS, resolveMarketingMarquee, renderMarketingMarqueeHtml, diagramMetrics };
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
assertArticleAuthor,
|
|
7
|
-
assertArticleCalloutTone,
|
|
8
|
-
assertArticleDates,
|
|
9
|
-
assertArticleHref,
|
|
10
|
-
formatArticleDate
|
|
2
|
+
escapeArticleHtml
|
|
3
|
+
} from "./chunk-6mx403v5.js";
|
|
4
|
+
import {
|
|
5
|
+
assertArticleHref
|
|
11
6
|
} from "./chunk-77391vmq.js";
|
|
12
7
|
import {
|
|
13
8
|
mixPaletteColor,
|
|
14
9
|
paletteContrast,
|
|
15
10
|
readablePaletteColor
|
|
16
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-w1y1m3m7.js";
|
|
17
12
|
|
|
18
13
|
// src/palettes.ts
|
|
19
14
|
var designPalettes = ["catppuccin", "gruvbox", "rose-pine", "tokyo-night", "paper"];
|
|
@@ -424,132 +419,6 @@ function getDesignPaletteTheme(palette, mode) {
|
|
|
424
419
|
background: paletteColors[palette][mode].background
|
|
425
420
|
};
|
|
426
421
|
}
|
|
427
|
-
// src/article-html.ts
|
|
428
|
-
var ROOT_CLASS = "plain-site plain-publication plain-publication--embedded";
|
|
429
|
-
var SEPARATOR = '<span aria-hidden="true"> · </span>';
|
|
430
|
-
var ESCAPES = {
|
|
431
|
-
'"': """,
|
|
432
|
-
"&": "&",
|
|
433
|
-
"'": "'",
|
|
434
|
-
"<": "<",
|
|
435
|
-
">": ">"
|
|
436
|
-
};
|
|
437
|
-
function escapeArticleHtml(value) {
|
|
438
|
-
return value.replace(/["&'<>]/gu, (character) => ESCAPES[character] ?? character);
|
|
439
|
-
}
|
|
440
|
-
function classes2(...values) {
|
|
441
|
-
return values.filter((value) => value !== undefined && value !== "").join(" ");
|
|
442
|
-
}
|
|
443
|
-
function dateHtml(label, value) {
|
|
444
|
-
return `${label} <time dateTime="${escapeArticleHtml(value)}">${escapeArticleHtml(formatArticleDate(value))}</time>`;
|
|
445
|
-
}
|
|
446
|
-
function present(value) {
|
|
447
|
-
return value !== undefined && value !== "";
|
|
448
|
-
}
|
|
449
|
-
function renderArticleBylineHtml(author) {
|
|
450
|
-
assertArticleAuthor(author);
|
|
451
|
-
const name = escapeArticleHtml(author.name);
|
|
452
|
-
const linked = author.href === undefined ? name : `<a href="${escapeArticleHtml(author.href)}" rel="author">${name}</a>`;
|
|
453
|
-
return `<span class="plain-publication__byline" data-author-kind="${author.kind}">${ARTICLE_BYLINE_PREFIX} ${linked}</span>`;
|
|
454
|
-
}
|
|
455
|
-
function renderArticleProvenanceHtml(provenance) {
|
|
456
|
-
const sentence = articleProvenanceSentence(provenance);
|
|
457
|
-
return `<p class="plain-publication__provenance" data-drafting="${escapeArticleHtml(provenance.drafting)}" data-reviewer-type="${escapeArticleHtml(provenance.review?.reviewerType ?? "none")}">${escapeArticleHtml(sentence)}</p>`;
|
|
458
|
-
}
|
|
459
|
-
function renderArticleHtml(input) {
|
|
460
|
-
const headingId = input.headingId ?? "article-title";
|
|
461
|
-
const {
|
|
462
|
-
published,
|
|
463
|
-
updated,
|
|
464
|
-
showDates = true
|
|
465
|
-
} = input;
|
|
466
|
-
assertArticleDates(updated === undefined ? {
|
|
467
|
-
published
|
|
468
|
-
} : {
|
|
469
|
-
published,
|
|
470
|
-
updated
|
|
471
|
-
});
|
|
472
|
-
const toc = input.toc ?? [];
|
|
473
|
-
for (const item of toc) {
|
|
474
|
-
if (!item.href.startsWith("#") || item.href.length < 2)
|
|
475
|
-
throw new RangeError("Contents links must point to a heading in this article.");
|
|
476
|
-
}
|
|
477
|
-
const tocId = `${headingId}-contents`;
|
|
478
|
-
const meta = [input.author === undefined ? "" : renderArticleBylineHtml(input.author), showDates ? dateHtml("Published", published) : "", showDates && updated !== undefined ? dateHtml("Updated", updated) : ""].filter(Boolean).join(SEPARATOR);
|
|
479
|
-
const header = ['<header class="plain-publication__article-header">', present(input.eyebrow) ? `<p class="plain-publication__eyebrow">${escapeArticleHtml(input.eyebrow)}</p>` : "", `<h1 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(input.heading)}</h1>`, present(input.dek) ? `<p class="plain-publication__article-dek">${escapeArticleHtml(input.dek)}</p>` : "", meta === "" ? "" : `<p class="plain-publication__article-meta">${meta}</p>`, input.provenance === null ? "" : renderArticleProvenanceHtml(input.provenance), "</header>"].join("");
|
|
480
|
-
const nav = toc.length === 0 ? "" : [`<nav aria-labelledby="${escapeArticleHtml(tocId)}" class="plain-publication__toc">`, `<p id="${escapeArticleHtml(tocId)}">${escapeArticleHtml(input.tocLabel ?? ARTICLE_TOC_LABEL)}</p>`, "<ol>", ...toc.map((item) => `<li><a href="${escapeArticleHtml(item.href)}">${escapeArticleHtml(item.label)}</a></li>`), "</ol></nav>"].join("");
|
|
481
|
-
return [`<article aria-labelledby="${escapeArticleHtml(headingId)}" class="${escapeArticleHtml(classes2(ROOT_CLASS, "plain-publication__article", input.className))}" data-hraness-article="" data-toc="${toc.length > 0 ? "aside" : "none"}"${input.id === undefined ? "" : ` id="${escapeArticleHtml(input.id)}"`}>`, header, '<div class="plain-publication__article-layout">', nav, `<div class="plain-publication__article-body">${input.bodyHtml}</div>`, "</div>", present(input.afterHtml) ? `<footer class="plain-publication__article-footer">${input.afterHtml}</footer>` : "", "</article>"].join("");
|
|
482
|
-
}
|
|
483
|
-
function renderArticleSourcesHtml({
|
|
484
|
-
heading = ARTICLE_SOURCES_HEADING,
|
|
485
|
-
headingId = "article-sources",
|
|
486
|
-
showDates = true,
|
|
487
|
-
sources
|
|
488
|
-
}) {
|
|
489
|
-
if (sources.length === 0)
|
|
490
|
-
return "";
|
|
491
|
-
for (const source of sources) {
|
|
492
|
-
assertArticleHref(source.href);
|
|
493
|
-
formatArticleDate(source.checkedOn);
|
|
494
|
-
}
|
|
495
|
-
return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="plain-publication__sources">`, `<h2 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</h2>`, "<ol>", ...sources.map((source) => {
|
|
496
|
-
const meta = [present(source.publisher) ? escapeArticleHtml(source.publisher) : "", showDates ? dateHtml("Checked", source.checkedOn) : ""].filter(Boolean).join(SEPARATOR);
|
|
497
|
-
return [`<li><a href="${escapeArticleHtml(source.href)}">${escapeArticleHtml(source.title)}</a>`, meta === "" ? "" : `<span>${meta}</span>`, "</li>"].join("");
|
|
498
|
-
}), "</ol></section>"].join("");
|
|
499
|
-
}
|
|
500
|
-
function renderArticleCalloutHtml(input) {
|
|
501
|
-
const tone = input.tone ?? "note";
|
|
502
|
-
assertArticleCalloutTone(tone);
|
|
503
|
-
const body = input.text === undefined ? input.bodyHtml : `<p>${escapeArticleHtml(input.text)}</p>`;
|
|
504
|
-
return `<div class="plain-publication__callout" data-tone="${tone}" role="note">${present(input.label) ? `<strong>${escapeArticleHtml(input.label)}</strong>` : ""}${body}</div>`;
|
|
505
|
-
}
|
|
506
|
-
function assertArticleMark(mark) {
|
|
507
|
-
if (!mark.startsWith("data:image/svg+xml,"))
|
|
508
|
-
assertArticleHref(mark);
|
|
509
|
-
}
|
|
510
|
-
function renderArticleRelatedHtml({
|
|
511
|
-
heading = "Related products",
|
|
512
|
-
headingId = "article-related-products",
|
|
513
|
-
items
|
|
514
|
-
}) {
|
|
515
|
-
if (items.length === 0)
|
|
516
|
-
return "";
|
|
517
|
-
for (const item of items) {
|
|
518
|
-
assertArticleHref(item.href);
|
|
519
|
-
if (present(item.mark))
|
|
520
|
-
assertArticleMark(item.mark);
|
|
521
|
-
}
|
|
522
|
-
return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="plain-publication__related">`, `<div class="plain-publication__section-heading"><h2 id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</h2></div>`, '<div class="plain-publication__related-grid">', ...items.map((item) => [`<a href="${escapeArticleHtml(item.href)}">`, present(item.mark) ? `<img alt="" class="plain-publication__related-mark" decoding="async" height="44" src="${escapeArticleHtml(item.mark)}" width="44">` : "", `<span class="plain-publication__related-text"><strong>${escapeArticleHtml(item.name)}</strong>`, `<span>${escapeArticleHtml(item.role ?? item.relationship)}</span></span></a>`].join("")), "</div></section>"].join("");
|
|
523
|
-
}
|
|
524
|
-
function renderArticleIndexHtml({
|
|
525
|
-
className,
|
|
526
|
-
heading,
|
|
527
|
-
headingId,
|
|
528
|
-
headingLevel = 2,
|
|
529
|
-
id,
|
|
530
|
-
items,
|
|
531
|
-
showDates = true,
|
|
532
|
-
summary
|
|
533
|
-
}) {
|
|
534
|
-
if (![1, 2, 3, 4, 5].includes(headingLevel))
|
|
535
|
-
throw new RangeError("Article index heading level must be 1 to 5.");
|
|
536
|
-
const hrefs = new Set;
|
|
537
|
-
for (const item of items) {
|
|
538
|
-
assertArticleHref(item.href);
|
|
539
|
-
assertArticleDates(item.updated === undefined ? {
|
|
540
|
-
published: item.published
|
|
541
|
-
} : {
|
|
542
|
-
published: item.published,
|
|
543
|
-
updated: item.updated
|
|
544
|
-
});
|
|
545
|
-
if (hrefs.has(item.href))
|
|
546
|
-
throw new RangeError(`Article index lists ${item.href} more than once.`);
|
|
547
|
-
hrefs.add(item.href);
|
|
548
|
-
}
|
|
549
|
-
const heading1 = `h${headingLevel}`;
|
|
550
|
-
const entry = `h${headingLevel + 1}`;
|
|
551
|
-
return [`<section aria-labelledby="${escapeArticleHtml(headingId)}" class="${escapeArticleHtml(classes2(ROOT_CLASS, "plain-publication__list", className))}" data-hraness-article-index=""${id === undefined ? "" : ` id="${escapeArticleHtml(id)}"`}>`, `<div class="plain-publication__section-heading"><${heading1} id="${escapeArticleHtml(headingId)}">${escapeArticleHtml(heading)}</${heading1}>`, present(summary) ? `<p>${escapeArticleHtml(summary)}</p>` : "", "</div>", '<div class="plain-publication__article-list">', ...items.map((item) => ['<article class="plain-publication__entry">', present(item.eyebrow) ? `<p class="plain-publication__entry-label">${escapeArticleHtml(item.eyebrow)}</p>` : "", `<${entry} class="plain-publication__entry-title"><a href="${escapeArticleHtml(item.href)}">${escapeArticleHtml(item.title)}</a></${entry}>`, `<p class="plain-publication__entry-dek">${escapeArticleHtml(item.dek)}</p>`, showDates ? ['<p class="plain-publication__entry-meta">', dateHtml("Published", item.published), item.updated === undefined ? "" : SEPARATOR + dateHtml("Updated", item.updated), "</p>"].join("") : "", "</article>"].join("")), "</div></section>"].join("");
|
|
552
|
-
}
|
|
553
422
|
// src/status-page.ts
|
|
554
423
|
var STATUS_PAGE_MAX_NEXT = 3;
|
|
555
424
|
var STATUS_PAGE_MAX_ROUTES = 2000;
|
|
@@ -1243,4 +1112,4 @@ function themeFor(mode) {
|
|
|
1243
1112
|
return colors[mode];
|
|
1244
1113
|
}
|
|
1245
1114
|
|
|
1246
|
-
export { designPalettes, designPaletteLabels, isDesignPalette, designPaletteSources, paletteColors, designThemes, defaultDesignTheme, designThemeStorageKey, isDesignTheme, normalizeDesignTheme, designThemeLabel, resolveDesignTheme, defaultDesignPalettePreference, designPaletteStorageKey, parseDesignPalettePreference, normalizeDesignPalettePreference, resolveDesignPalettePreference, getDesignPaletteTheme,
|
|
1115
|
+
export { designPalettes, designPaletteLabels, isDesignPalette, designPaletteSources, paletteColors, designThemes, defaultDesignTheme, designThemeStorageKey, isDesignTheme, normalizeDesignTheme, designThemeLabel, resolveDesignTheme, defaultDesignPalettePreference, designPaletteStorageKey, parseDesignPalettePreference, normalizeDesignPalettePreference, resolveDesignPalettePreference, getDesignPaletteTheme, STATUS_PAGE_MAX_NEXT, STATUS_PAGE_MAX_ROUTES, STATUS_PAGE_BACK_LABEL, STATUS_PAGE_HINT_PREFIX, STATUS_PAGE_NEXT_HEADING_ID, STATUS_PAGE_AGENT_PREFIX, resolveStatusPage, statusPageRoutesAttribute, parseStatusPageRoutes, normalizeStatusPath, suggestStatusRoute, renderStatusPageHtml, relativeTimeUnits, parseRelativeTimeInput, resolveRelativeTime, formatRelativeTime, MAX_AGENT_SETUP_URL, agentSetupTargets, colors, auroraColors, chromeColors, chromeGradientStops, spacing, radius, controlRadius, layout, siteThemes, interaction, motion, elevation, stacking, breakpoints, iconography, typeScale, fontWeights, fontFamilies, fontFallbacks, typography, themeFor };
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
SampleText,
|
|
8
8
|
WindowLights,
|
|
9
9
|
compact
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-fcs5qekr.js";
|
|
11
11
|
// src/mockups/frames.tsx
|
|
12
12
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
13
13
|
var MOCKUP_EXAMPLE_HOST = /(^|\.)(example(\.(com|net|org))?|test|invalid|localhost)$/u;
|