@certrev/cert-block 0.1.3 → 0.2.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/components/CertBadge.d.ts +18 -3
- package/dist/components/CertBadge.d.ts.map +1 -1
- package/dist/components/CertBadge.js +8 -2
- package/dist/components/CertBadge.js.map +1 -1
- package/dist/components/CertReview.d.ts +7 -0
- package/dist/components/CertReview.d.ts.map +1 -1
- package/dist/components/CertReview.js +1 -1
- package/dist/components/CertReview.js.map +1 -1
- package/dist/components/format.d.ts +14 -2
- package/dist/components/format.d.ts.map +1 -1
- package/dist/components/format.js +18 -5
- package/dist/components/format.js.map +1 -1
- package/dist/components/render-cert-block.d.ts +89 -0
- package/dist/components/render-cert-block.d.ts.map +1 -0
- package/dist/components/render-cert-block.js +282 -0
- package/dist/components/render-cert-block.js.map +1 -0
- package/dist/components/render-def.d.ts +178 -0
- package/dist/components/render-def.d.ts.map +1 -0
- package/dist/components/render-def.js +204 -0
- package/dist/components/render-def.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/webcomponent/render-badge-html.d.ts +8 -0
- package/dist/webcomponent/render-badge-html.d.ts.map +1 -1
- package/dist/webcomponent/render-badge-html.js +31 -4
- package/dist/webcomponent/render-badge-html.js.map +1 -1
- package/package.json +77 -76
- package/src/__tests__/__snapshots__/render-cert-block.test.ts.snap +13 -0
- package/src/__tests__/components.test.tsx +16 -1
- package/src/__tests__/render-cert-block.test.ts +259 -0
- package/src/__tests__/render-def.test.tsx +286 -0
- package/src/__tests__/webcomponent.test.tsx +10 -0
- package/src/components/CertBadge.tsx +56 -4
- package/src/components/CertReview.tsx +8 -0
- package/src/components/format.ts +22 -5
- package/src/components/render-cert-block.ts +403 -0
- package/src/components/render-def.ts +286 -0
- package/src/index.ts +35 -0
- package/src/webcomponent/render-badge-html.ts +46 -4
|
@@ -11,19 +11,34 @@
|
|
|
11
11
|
* an inline custom property (no color-only meaning — the credential text carries it), an
|
|
12
12
|
* expert photo with meaningful alt text, and a verify link with a descriptive label.
|
|
13
13
|
*
|
|
14
|
-
* `badgeStyle: 'compact'` collapses to a single line (name + credentials
|
|
15
|
-
* `'full'` shows the photo, certified/updated dates, and the memo (per display flags).
|
|
14
|
+
* `badgeStyle: 'compact'` collapses the reviewer block to a single line (name + credentials);
|
|
15
|
+
* `'full'` shows the photo, certified/updated dates, and the memo (per display flags). BOTH
|
|
16
|
+
* styles carry the compensation cue + FTC scope line (the always-on compliance disclosures).
|
|
17
|
+
*
|
|
18
|
+
* THEMING (WS6): presentation defaults come from `payload.content.display`; an optional
|
|
19
|
+
* `renderDef` prop layers a brand's validated themeable tokens (emitted as `--certrev-*`
|
|
20
|
+
* CSS custom properties) and its subtractive field-visibility on top. No `renderDef` → the
|
|
21
|
+
* CertREV preset default (theme output byte-identical to un-themed).
|
|
16
22
|
*/
|
|
17
23
|
import type { CertPayload } from '../contract/kernel.js';
|
|
24
|
+
import { type CertRenderDef } from './render-def.js';
|
|
18
25
|
export interface CertBadgeProps {
|
|
19
26
|
/** The cryptographically-verified payload (from `getVerifiedEnvelope`). */
|
|
20
27
|
readonly payload: CertPayload;
|
|
21
|
-
/** Optional accent override (else `display.accentColor`, else CertREV default). */
|
|
28
|
+
/** Optional accent override (else render-def, else `display.accentColor`, else CertREV default). */
|
|
22
29
|
readonly accentColor?: string;
|
|
23
30
|
/** Extra class names appended to the root element's class list. */
|
|
24
31
|
readonly className?: string;
|
|
25
32
|
/** Override the badge style independent of the signed display config. */
|
|
26
33
|
readonly badgeStyle?: 'full' | 'compact';
|
|
34
|
+
/**
|
|
35
|
+
* The brand render-def (WS6). ABSENT → the badge renders the CertREV preset
|
|
36
|
+
* default (fail-safe; theme output byte-identical to un-themed). PRESENT → its
|
|
37
|
+
* validated themeable tokens are emitted as `--certrev-*` CSS custom properties
|
|
38
|
+
* and its subtractive hide-set removes brand-toggleable fields. Invalid tokens
|
|
39
|
+
* are dropped (defense-in-depth over the write-path gate).
|
|
40
|
+
*/
|
|
41
|
+
readonly renderDef?: CertRenderDef;
|
|
27
42
|
}
|
|
28
43
|
export declare function CertBadge(props: CertBadgeProps): import("react").JSX.Element;
|
|
29
44
|
//# sourceMappingURL=CertBadge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertBadge.d.ts","sourceRoot":"","sources":["../../src/components/CertBadge.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"CertBadge.d.ts","sourceRoot":"","sources":["../../src/components/CertBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGrE,OAAO,EAGN,KAAK,aAAa,EAGlB,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,cAAc;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,oGAAoG;IACpG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAA;CAClC;AAuCD,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,+BA6H9C"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { safeHttpUrl } from './escape.js';
|
|
3
3
|
import { credentialSuffix, expertNameWithCredentials, formatDate, resolveDisplay } from './format.js';
|
|
4
|
+
import { CERT_SCOPE_LINE, CERT_STRINGS_VERSION, resolveRenderTheme, themeCssVarDeclarations, } from './render-def.js';
|
|
4
5
|
const ROOT_CLASS = 'certrev-badge';
|
|
5
6
|
/** Inline-SVG verified checkmark — no external asset, accent-tinted, decorative. */
|
|
6
7
|
function VerifiedMark({ accent }) {
|
|
@@ -15,7 +16,8 @@ function ExpertPhoto({ content, show }) {
|
|
|
15
16
|
export function CertBadge(props) {
|
|
16
17
|
const { payload } = props;
|
|
17
18
|
const content = payload.content;
|
|
18
|
-
const display = resolveDisplay(content.display, props.accentColor);
|
|
19
|
+
const display = resolveDisplay(content.display, props.accentColor, props.renderDef);
|
|
20
|
+
const theme = resolveRenderTheme(props.renderDef);
|
|
19
21
|
const style = props.badgeStyle ?? display.badgeStyle;
|
|
20
22
|
const verifyUrl = safeHttpUrl(content.verifyUrl);
|
|
21
23
|
const profileUrl = safeHttpUrl(content.expert.profileUrl);
|
|
@@ -26,11 +28,15 @@ export function CertBadge(props) {
|
|
|
26
28
|
const rootClass = `${ROOT_CLASS} ${ROOT_CLASS}--${style}${props.className ? ` ${props.className}` : ''}`;
|
|
27
29
|
// Accent is exposed as a custom property so brand themes can read it, and applied
|
|
28
30
|
// directly to the accent border so the component is self-styling without a stylesheet.
|
|
31
|
+
// A THEMED brand additionally emits the surface/radius/font vars; with no render-def
|
|
32
|
+
// `themeCssVarDeclarations` is empty, so the un-themed style is byte-identical.
|
|
29
33
|
const rootStyle = {
|
|
30
34
|
['--certrev-accent']: accent,
|
|
31
35
|
borderInlineStartColor: accent,
|
|
32
36
|
};
|
|
37
|
+
for (const [name, value] of themeCssVarDeclarations(theme))
|
|
38
|
+
rootStyle[name] = value;
|
|
33
39
|
const expertName = (_jsxs("span", { className: `${ROOT_CLASS}__expert-name`, children: [content.expert.displayName, suffix ? _jsxs("span", { className: `${ROOT_CLASS}__credentials`, children: [", ", suffix] }) : null] }));
|
|
34
|
-
return (_jsxs("section", { className: rootClass, style: rootStyle, "data-certrev-cert-id": payload.certId, "aria-label": `Content reviewed by ${expertNameWithCredentials(content)}`, children: [_jsxs("div", { className: `${ROOT_CLASS}__header`, children: [_jsx(VerifiedMark, { accent: accent }), style === 'full' ? _jsx(ExpertPhoto, { content: content, show: display.showExpertPhoto }) : null, _jsxs("div", { className: `${ROOT_CLASS}__heading`, children: [_jsx("span", { className: `${ROOT_CLASS}__eyebrow`, children: "Expert reviewed" }), _jsxs("span", { className: `${ROOT_CLASS}__byline`, children: ["Reviewed by", ' ', profileUrl ? (_jsx("a", { className: `${ROOT_CLASS}__expert-link`, href: profileUrl, rel: "noopener", children: expertName })) : (expertName)] })] })] }), style === 'full' ? (_jsxs(_Fragment, { children: [display.showMemo && content.memo ? _jsx("p", { className: `${ROOT_CLASS}__memo`, children: content.memo }) : null, display.showAuthor && content.author.name && content.author.name !== content.expert.displayName ? (_jsxs("p", { className: `${ROOT_CLASS}__author`, children: ["Written by ", content.author.name, content.author.title ? `, ${content.author.title}` : ''] })) : null, _jsxs("dl", { className: `${ROOT_CLASS}__dates`, children: [certifiedLabel ? (_jsxs("div", { className: `${ROOT_CLASS}__date`, children: [_jsx("dt", { children: "Certified" }), _jsx("dd", { children: _jsx("time", { dateTime: content.certifiedAt, children: certifiedLabel }) })] })) : null, updatedLabel ? (_jsxs("div", { className: `${ROOT_CLASS}__date`, children: [_jsx("dt", { children: "Last updated" }), _jsx("dd", { children: _jsx("time", { dateTime: content.contentModifiedAt ?? undefined, children: updatedLabel }) })] })) : null] })] })) : null, verifyUrl ? (_jsx("a", { className: `${ROOT_CLASS}__verify`, href: verifyUrl, rel: "noopener", "aria-label": "Verify this certification on CertREV", children: "Verify on CertREV" })) : null] }));
|
|
40
|
+
return (_jsxs("section", { className: rootClass, style: rootStyle, "data-certrev-cert-id": payload.certId, "data-certrev-strings-version": CERT_STRINGS_VERSION, "data-certrev-def-version": theme.version, "aria-label": `Content reviewed by ${expertNameWithCredentials(content)}`, children: [_jsxs("div", { className: `${ROOT_CLASS}__header`, children: [_jsx(VerifiedMark, { accent: accent }), style === 'full' ? _jsx(ExpertPhoto, { content: content, show: display.showExpertPhoto }) : null, _jsxs("div", { className: `${ROOT_CLASS}__heading`, children: [_jsx("span", { className: `${ROOT_CLASS}__eyebrow`, children: "Expert reviewed" }), _jsxs("span", { className: `${ROOT_CLASS}__byline`, children: ["Reviewed by", ' ', profileUrl ? (_jsx("a", { className: `${ROOT_CLASS}__expert-link`, href: profileUrl, rel: "noopener", children: expertName })) : (expertName)] })] })] }), style === 'full' ? (_jsxs(_Fragment, { children: [display.showMemo && content.memo ? _jsx("p", { className: `${ROOT_CLASS}__memo`, children: content.memo }) : null, display.showAuthor && content.author.name && content.author.name !== content.expert.displayName ? (_jsxs("p", { className: `${ROOT_CLASS}__author`, children: ["Written by ", content.author.name, content.author.title ? `, ${content.author.title}` : ''] })) : null, _jsxs("dl", { className: `${ROOT_CLASS}__dates`, children: [certifiedLabel ? (_jsxs("div", { className: `${ROOT_CLASS}__date`, children: [_jsx("dt", { children: "Certified" }), _jsx("dd", { children: _jsx("time", { dateTime: content.certifiedAt, children: certifiedLabel }) })] })) : null, updatedLabel ? (_jsxs("div", { className: `${ROOT_CLASS}__date`, children: [_jsx("dt", { children: "Last updated" }), _jsx("dd", { children: _jsx("time", { dateTime: content.contentModifiedAt ?? undefined, children: updatedLabel }) })] })) : null] })] })) : null, _jsxs("div", { className: `${ROOT_CLASS}__disclosure`, children: [_jsxs("span", { className: `${ROOT_CLASS}__compensated-cue`, children: ["Compensated", ' ', profileUrl ? (_jsx("a", { className: `${ROOT_CLASS}__cue-link`, href: profileUrl, rel: "noopener", children: "expert" })) : ('expert')] }), _jsx("p", { className: `${ROOT_CLASS}__ftc`, "data-ftc-disclosure": true, children: _jsx("span", { "data-ftc-line": true, children: CERT_SCOPE_LINE }) })] }), verifyUrl ? (_jsx("a", { className: `${ROOT_CLASS}__verify`, href: verifyUrl, rel: "noopener", "aria-label": "Verify this certification on CertREV", children: "Verify on CertREV" })) : null] }));
|
|
35
41
|
}
|
|
36
42
|
//# sourceMappingURL=CertBadge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertBadge.js","sourceRoot":"","sources":["../../src/components/CertBadge.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"CertBadge.js","sourceRoot":"","sources":["../../src/components/CertBadge.tsx"],"names":[],"mappings":";AAwBA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACrG,OAAO,EACN,eAAe,EACf,oBAAoB,EAEpB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAA;AAqBxB,MAAM,UAAU,GAAG,eAAe,CAAA;AAElC,oFAAoF;AACpF,SAAS,YAAY,CAAC,EAAE,MAAM,EAAsB;IACnD,OAAO,CACN,eACC,SAAS,EAAE,GAAG,UAAU,QAAQ,EAChC,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,iBACC,MAAM,EAClB,SAAS,EAAC,OAAO,aAEjB,uCAAuB,EACvB,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,EAAC,IAAI,EAAE,MAAM,GAAI,EAC/C,eAAM,CAAC,EAAC,sBAAsB,EAAC,MAAM,EAAC,SAAS,EAAC,WAAW,EAAC,KAAK,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,GAAG,IAC5G,CACN,CAAA;AACF,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,EAA2C;IAC9E,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9D,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,OAAO,CACN,cACC,SAAS,EAAE,GAAG,UAAU,SAAS,EACjC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,YAAY,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,EAC7C,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,OAAO,EAAC,MAAM,EACd,QAAQ,EAAC,OAAO,GACf,CACF,CAAA;AACF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC9C,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;IACzB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;IAC/B,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACnF,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAA;IACpD,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAChD,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACzD,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACtD,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAA;IAElC,MAAM,SAAS,GAAG,GAAG,UAAU,IAAI,UAAU,KAAK,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IACxG,kFAAkF;IAClF,uFAAuF;IACvF,qFAAqF;IACrF,gFAAgF;IAChF,MAAM,SAAS,GAA2B;QACzC,CAAC,kBAAkB,CAAC,EAAE,MAAM;QAC5B,sBAAsB,EAAE,MAAM;KAC9B,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,uBAAuB,CAAC,KAAK,CAAC;QAAE,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;IAEnF,MAAM,UAAU,GAAG,CAClB,gBAAM,SAAS,EAAE,GAAG,UAAU,eAAe,aAC3C,OAAO,CAAC,MAAM,CAAC,WAAW,EAC1B,MAAM,CAAC,CAAC,CAAC,gBAAM,SAAS,EAAE,GAAG,UAAU,eAAe,mBAAK,MAAM,IAAQ,CAAC,CAAC,CAAC,IAAI,IAC3E,CACP,CAAA;IAED,OAAO,CACN,mBACC,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,SAAS,0BACM,OAAO,CAAC,MAAM,kCACN,oBAAoB,8BACxB,KAAK,CAAC,OAAO,gBAC3B,uBAAuB,yBAAyB,CAAC,OAAO,CAAC,EAAE,aAEvE,eAAK,SAAS,EAAE,GAAG,UAAU,UAAU,aACtC,KAAC,YAAY,IAAC,MAAM,EAAE,MAAM,GAAI,EAC/B,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAC,WAAW,IAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,eAAe,GAAI,CAAC,CAAC,CAAC,IAAI,EAC3F,eAAK,SAAS,EAAE,GAAG,UAAU,WAAW,aACvC,eAAM,SAAS,EAAE,GAAG,UAAU,WAAW,gCAAwB,EACjE,gBAAM,SAAS,EAAE,GAAG,UAAU,UAAU,4BAC3B,GAAG,EACd,UAAU,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAE,GAAG,UAAU,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAC,UAAU,YAC1E,UAAU,GACR,CACJ,CAAC,CAAC,CAAC,CACH,UAAU,CACV,IACK,IACF,IACD,EAEL,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CACnB,8BACE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,YAAG,SAAS,EAAE,GAAG,UAAU,QAAQ,YAAG,OAAO,CAAC,IAAI,GAAK,CAAC,CAAC,CAAC,IAAI,EACjG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAClG,aAAG,SAAS,EAAE,GAAG,UAAU,UAAU,4BACxB,OAAO,CAAC,MAAM,CAAC,IAAI,EAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IACrD,CACJ,CAAC,CAAC,CAAC,IAAI,EACR,cAAI,SAAS,EAAE,GAAG,UAAU,SAAS,aACnC,cAAc,CAAC,CAAC,CAAC,CACjB,eAAK,SAAS,EAAE,GAAG,UAAU,QAAQ,aACpC,qCAAkB,EAClB,uBACC,eAAM,QAAQ,EAAE,OAAO,CAAC,WAAW,YAAG,cAAc,GAAQ,GACxD,IACA,CACN,CAAC,CAAC,CAAC,IAAI,EACP,YAAY,CAAC,CAAC,CAAC,CACf,eAAK,SAAS,EAAE,GAAG,UAAU,QAAQ,aACpC,wCAAqB,EACrB,uBACC,eAAM,QAAQ,EAAE,OAAO,CAAC,iBAAiB,IAAI,SAAS,YAAG,YAAY,GAAQ,GACzE,IACA,CACN,CAAC,CAAC,CAAC,IAAI,IACJ,IACH,CACH,CAAC,CAAC,CAAC,IAAI,EAWR,eAAK,SAAS,EAAE,GAAG,UAAU,cAAc,aAC1C,gBAAM,SAAS,EAAE,GAAG,UAAU,mBAAmB,4BACpC,GAAG,EACd,UAAU,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAE,GAAG,UAAU,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAC,UAAU,uBAErE,CACJ,CAAC,CAAC,CAAC,CACH,QAAQ,CACR,IACK,EACP,YAAG,SAAS,EAAE,GAAG,UAAU,OAAO,yCACjC,gDAAqB,eAAe,GAAQ,GACzC,IACC,EAEL,SAAS,CAAC,CAAC,CAAC,CACZ,YACC,SAAS,EAAE,GAAG,UAAU,UAAU,EAClC,IAAI,EAAE,SAAS,EACf,GAAG,EAAC,UAAU,gBACH,sCAAsC,kCAG9C,CACJ,CAAC,CAAC,CAAC,IAAI,IACC,CACV,CAAA;AACF,CAAC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* expert bio + backlink remain separately placeable for brands that want finer control.
|
|
9
9
|
*/
|
|
10
10
|
import type { CertVerdict } from '../contract/kernel.js';
|
|
11
|
+
import type { CertRenderDef } from './render-def.js';
|
|
11
12
|
export interface CertReviewProps {
|
|
12
13
|
/** The verdict from `getVerifiedEnvelope` (or a direct kernel call). */
|
|
13
14
|
readonly verdict: CertVerdict;
|
|
@@ -16,6 +17,12 @@ export interface CertReviewProps {
|
|
|
16
17
|
readonly accentColor?: string;
|
|
17
18
|
readonly className?: string;
|
|
18
19
|
readonly badgeStyle?: 'full' | 'compact';
|
|
20
|
+
/**
|
|
21
|
+
* The brand render-def (WS6). Forwarded to `<CertBadge>` for themeable-token
|
|
22
|
+
* emission + subtractive visibility; absent → the CertREV preset default. The
|
|
23
|
+
* JSON-LD is presentation-blind, so the def never touches the structured data.
|
|
24
|
+
*/
|
|
25
|
+
readonly renderDef?: CertRenderDef;
|
|
19
26
|
/** Omit the JSON-LD (e.g. the page already emits it elsewhere). Default false. */
|
|
20
27
|
readonly omitJsonLd?: boolean;
|
|
21
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertReview.d.ts","sourceRoot":"","sources":["../../src/components/CertReview.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"CertReview.d.ts","sourceRoot":"","sources":["../../src/components/CertReview.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,uFAAuF;IACvF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAA;IAClC,kFAAkF;IAClF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,sCAgBhD"}
|
|
@@ -6,6 +6,6 @@ export function CertReview(props) {
|
|
|
6
6
|
if (props.verdict.decision !== 'render')
|
|
7
7
|
return null;
|
|
8
8
|
const payload = props.verdict.payload;
|
|
9
|
-
return (_jsxs(_Fragment, { children: [_jsx(CertBadge, { payload: payload, accentColor: props.accentColor, className: props.className, badgeStyle: props.badgeStyle }), props.omitJsonLd ? null : _jsx(CertJsonLd, { payload: payload, pageUrl: props.pageUrl })] }));
|
|
9
|
+
return (_jsxs(_Fragment, { children: [_jsx(CertBadge, { payload: payload, accentColor: props.accentColor, className: props.className, badgeStyle: props.badgeStyle, renderDef: props.renderDef }), props.omitJsonLd ? null : _jsx(CertJsonLd, { payload: payload, pageUrl: props.pageUrl })] }));
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=CertReview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CertReview.js","sourceRoot":"","sources":["../../src/components/CertReview.tsx"],"names":[],"mappings":";AAWA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"CertReview.js","sourceRoot":"","sources":["../../src/components/CertReview.tsx"],"names":[],"mappings":";AAWA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAqB5C,MAAM,UAAU,UAAU,CAAC,KAAsB;IAChD,yEAAyE;IACzE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAA;IACrC,OAAO,CACN,8BACC,KAAC,SAAS,IACT,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,UAAU,EAAE,KAAK,CAAC,UAAU,EAC5B,SAAS,EAAE,KAAK,CAAC,SAAS,GACzB,EACD,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,UAAU,IAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,IACjF,CACH,CAAA;AACF,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* no React — so the same formatting drives JSX and the hand-built Web Component string.
|
|
4
4
|
*/
|
|
5
5
|
import type { CertContent, CertDisplayConfig } from '../contract/kernel.js';
|
|
6
|
+
import { type CertRenderDef } from './render-def.js';
|
|
6
7
|
/** Default accent if the brand didn't pin one (CertREV teal). */
|
|
7
8
|
export declare const DEFAULT_ACCENT = "#0f766e";
|
|
8
9
|
export interface ResolvedDisplay {
|
|
@@ -12,8 +13,19 @@ export interface ResolvedDisplay {
|
|
|
12
13
|
readonly showMemo: boolean;
|
|
13
14
|
readonly badgeStyle: 'full' | 'compact';
|
|
14
15
|
}
|
|
15
|
-
/**
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the optional display config + optional brand render-def to concrete
|
|
18
|
+
* presentation flags + accent.
|
|
19
|
+
*
|
|
20
|
+
* Accent PRECEDENCE mirrors the Shopify Liquid engine exactly: an explicit
|
|
21
|
+
* `accentOverride` (a block/prop override) wins, then the render-def's validated
|
|
22
|
+
* accent (a THEMED brand), then the signed display's accent, else the CertREV
|
|
23
|
+
* default. Visibility is SUBTRACTIVE: the render-def's hide-set can only turn a
|
|
24
|
+
* preset-placed field OFF (never on) — a hidden `reviewerPhoto` / `memo` wins over
|
|
25
|
+
* a display flag that shows it. When no render-def is supplied the theme resolves
|
|
26
|
+
* empty, so accent + visibility are byte-identical to the pre-theming behavior.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveDisplay(display: CertDisplayConfig | undefined, accentOverride?: string, renderDef?: CertRenderDef): ResolvedDisplay;
|
|
17
29
|
export declare function formatDate(iso: string | null | undefined): string | null;
|
|
18
30
|
/** "PhD, RD" — the expert's credential abbreviations, comma-joined. */
|
|
19
31
|
export declare function credentialSuffix(content: CertContent): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/components/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/components/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,EAAE,KAAK,aAAa,EAAqC,MAAM,iBAAiB,CAAA;AAEvF,iEAAiE;AACjE,eAAO,MAAM,cAAc,YAAY,CAAA;AAEvC,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,aAAa,GACvB,eAAe,CASjB;AAUD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAMxE;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAE7D;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAGtE"}
|
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
* Presentation helpers shared by the React components + Web Component. Pure, no DOM,
|
|
3
3
|
* no React — so the same formatting drives JSX and the hand-built Web Component string.
|
|
4
4
|
*/
|
|
5
|
+
import { isFieldHidden, resolveRenderTheme } from './render-def.js';
|
|
5
6
|
/** Default accent if the brand didn't pin one (CertREV teal). */
|
|
6
7
|
export const DEFAULT_ACCENT = '#0f766e';
|
|
7
|
-
/**
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the optional display config + optional brand render-def to concrete
|
|
10
|
+
* presentation flags + accent.
|
|
11
|
+
*
|
|
12
|
+
* Accent PRECEDENCE mirrors the Shopify Liquid engine exactly: an explicit
|
|
13
|
+
* `accentOverride` (a block/prop override) wins, then the render-def's validated
|
|
14
|
+
* accent (a THEMED brand), then the signed display's accent, else the CertREV
|
|
15
|
+
* default. Visibility is SUBTRACTIVE: the render-def's hide-set can only turn a
|
|
16
|
+
* preset-placed field OFF (never on) — a hidden `reviewerPhoto` / `memo` wins over
|
|
17
|
+
* a display flag that shows it. When no render-def is supplied the theme resolves
|
|
18
|
+
* empty, so accent + visibility are byte-identical to the pre-theming behavior.
|
|
19
|
+
*/
|
|
20
|
+
export function resolveDisplay(display, accentOverride, renderDef) {
|
|
21
|
+
const theme = resolveRenderTheme(renderDef);
|
|
9
22
|
return {
|
|
10
|
-
accentColor: accentOverride ?? display?.accentColor ?? DEFAULT_ACCENT,
|
|
11
|
-
showExpertPhoto: display?.showExpertPhoto ?? true,
|
|
23
|
+
accentColor: accentOverride ?? theme.accent ?? display?.accentColor ?? DEFAULT_ACCENT,
|
|
24
|
+
showExpertPhoto: (display?.showExpertPhoto ?? true) && !isFieldHidden(renderDef, 'reviewerPhoto'),
|
|
12
25
|
showAuthor: display?.showAuthor ?? true,
|
|
13
|
-
showMemo: display?.showMemo ?? true,
|
|
26
|
+
showMemo: (display?.showMemo ?? true) && !isFieldHidden(renderDef, 'memo'),
|
|
14
27
|
badgeStyle: display?.badgeStyle ?? 'full',
|
|
15
28
|
};
|
|
16
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/components/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/components/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAsB,aAAa,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEvF,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA;AAUvC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAsC,EACtC,cAAuB,EACvB,SAAyB;IAEzB,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;IAC3C,OAAO;QACN,WAAW,EAAE,cAAc,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,EAAE,WAAW,IAAI,cAAc;QACrF,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,eAAe,CAAC;QACjG,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI;QACvC,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC;QAC1E,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,MAAM;KACzC,CAAA;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;AAEnG,MAAM,UAAU,UAAU,CAAC,GAA8B;IACxD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;IACtB,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,cAAc,EAAE,EAAE,CAAA;AAC7E,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACpD,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACxE,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,yBAAyB,CAAC,OAAoB;IAC7D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACxC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAA;AACxF,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
* renderCertBlock — the LOCKED CertREV cert design, as an SSR-safe HTML string
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* Paints the owner-approved cert render (decision 2026-07-17) in one of three
|
|
7
|
+
* placement modes — `banner`, `sidebar`, `floating` — from RESOLVED theme tokens +
|
|
8
|
+
* the cert facts. It returns a self-contained HTML string that renders with ZERO
|
|
9
|
+
* JavaScript (the CertREV modal + the reviewer-bio accordion are progressive
|
|
10
|
+
* enhancement, wired by the shared embed script via the `data-certrev-*` hooks).
|
|
11
|
+
*
|
|
12
|
+
* WHY A STRING (not a React component): the block is emitted into storefront HTML
|
|
13
|
+
* across every render surface (Shopify Liquid, WordPress PHP, the JS engine, and
|
|
14
|
+
* this headless twin). A pure string renderer — like `renderBadgeHtml` — runs on
|
|
15
|
+
* every runtime the main entry targets (edge / Workers / server) with no React, no
|
|
16
|
+
* DOM, no Node builtins.
|
|
17
|
+
*
|
|
18
|
+
* THEMING: the reference is variable-driven. This emits the guide's CSS-var theming
|
|
19
|
+
* hooks on the ROOT element so the block is self-contained on a storefront that does
|
|
20
|
+
* NOT define the guide's `:root` — the accent (`--ba`), its auto-contrast ink
|
|
21
|
+
* (`--ba-fg`), the corner radius (`--br`), the body font (`--bf`) and surface
|
|
22
|
+
* (`--surface`) come from the resolved theme; the navy trust tints + the fixed
|
|
23
|
+
* label/serif/wordmark fonts are LOCKED literals (guide "the lock is legal, not
|
|
24
|
+
* aesthetic"). A brand themes accent / font / corners / surface; the navy chrome ink
|
|
25
|
+
* stays fixed.
|
|
26
|
+
*
|
|
27
|
+
* COMPLIANCE (LOCKED, non-negotiable): the three material disclosures always render
|
|
28
|
+
* on a CLAIM face (banner + sidebar) — the compensation cue, the byte-exact FTC
|
|
29
|
+
* scope line, and the dated credential verification, which stays GROUPED with the
|
|
30
|
+
* credential (`<name>, <credential>` → "Credential verified by CertREV" → "on
|
|
31
|
+
* <date>"). The `floating` pill makes no claim (it only labels + links to the
|
|
32
|
+
* modal), so it carries no disclosures — matching the locked reference.
|
|
33
|
+
*
|
|
34
|
+
* SECURITY: this is storefront HTML built by hand (no JSX auto-escaping), so EVERY
|
|
35
|
+
* interpolated value is escaped — `escapeHtml` for content, `escapeAttribute` for
|
|
36
|
+
* attribute values, `safeHttpUrl` for hrefs. Theme tokens are re-validated
|
|
37
|
+
* (`resolveBlockTheme`) and only ever emitted as strict hex / length / enum-stack.
|
|
38
|
+
*/
|
|
39
|
+
import { type ResolvedBlockTheme } from './render-def.js';
|
|
40
|
+
/** The three LOCKED placement faces. */
|
|
41
|
+
export type CertBlockMode = 'banner' | 'sidebar' | 'floating';
|
|
42
|
+
/**
|
|
43
|
+
* The cert facts + LOCKED display strings a face renders. Facts are escaped; the
|
|
44
|
+
* three locked strings (`compensationCue`, `scopeLine`, `credentialLine`) are
|
|
45
|
+
* byte-verbatim per the CertREV Display Guide and default to the mirrored constants
|
|
46
|
+
* when a caller omits them — so the compliance baseline is exact even if unsupplied.
|
|
47
|
+
*/
|
|
48
|
+
export interface CertBlockFacts {
|
|
49
|
+
/** The content author (the "Written by" column). */
|
|
50
|
+
readonly authorName: string;
|
|
51
|
+
/** The author's subtitle (e.g. "Editorial"). Omitted when absent. */
|
|
52
|
+
readonly authorTitle?: string;
|
|
53
|
+
/** The reviewing expert's display name, WITHOUT the credential (e.g. "Jane Doe"). */
|
|
54
|
+
readonly reviewerName: string;
|
|
55
|
+
/** The reviewer's credential abbreviation (e.g. "MD"). Empty → name-only. */
|
|
56
|
+
readonly credential: string;
|
|
57
|
+
/** ISO instant CertREV verified the CREDENTIAL (the dated verification date). */
|
|
58
|
+
readonly credentialVerifiedAt: string;
|
|
59
|
+
/** ISO instant the article was certified (the "Certified <date>" footer). */
|
|
60
|
+
readonly certifiedAt: string;
|
|
61
|
+
/** The expert's memo (rendered as the serif blockquote). */
|
|
62
|
+
readonly memo: string;
|
|
63
|
+
/** The expert's bio (banner accordion / sidebar paragraph). Omitted when absent. */
|
|
64
|
+
readonly bio?: string;
|
|
65
|
+
/** The expert profile URL (the "Profile" link + modal `expert` hook). */
|
|
66
|
+
readonly profileUrl: string;
|
|
67
|
+
/** The certificate URL (the "Certificate" link + modal hook). */
|
|
68
|
+
readonly certificateUrl: string;
|
|
69
|
+
/** LOCKED — the compensation cue. Default: `COMPENSATED_EXPERT_CUE`. */
|
|
70
|
+
readonly compensationCue?: string;
|
|
71
|
+
/** LOCKED — the byte-exact FTC scope line. Default: `CERT_SCOPE_LINE`. */
|
|
72
|
+
readonly scopeLine?: string;
|
|
73
|
+
/** LOCKED — the verification attribution. Default: `CREDENTIAL_VERIFIED_ATTRIBUTION`. */
|
|
74
|
+
readonly credentialLine?: string;
|
|
75
|
+
}
|
|
76
|
+
/** The full input to `renderCertBlock`. */
|
|
77
|
+
export interface RenderCertBlockInput {
|
|
78
|
+
readonly mode: CertBlockMode;
|
|
79
|
+
/** RESOLVED theme tokens (the portal bakes these). Absent/invalid tokens fall back to navy. */
|
|
80
|
+
readonly theme?: Partial<ResolvedBlockTheme>;
|
|
81
|
+
readonly facts: CertBlockFacts;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Render the LOCKED CertREV cert design as an SSR-safe HTML string for one of the
|
|
85
|
+
* three placement modes. Returns a self-contained `<div class="certrev-cert …">`
|
|
86
|
+
* that needs no JS to render (the modal + bio accordion progressively enhance).
|
|
87
|
+
*/
|
|
88
|
+
export declare function renderCertBlock(input: RenderCertBlockInput): string;
|
|
89
|
+
//# sourceMappingURL=render-cert-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-cert-block.d.ts","sourceRoot":"","sources":["../../src/components/render-cert-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAIH,OAAO,EAMN,KAAK,kBAAkB,EAEvB,MAAM,iBAAiB,CAAA;AAExB,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oFAAoF;IACpF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAC9B;AAmSD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAWnE"}
|