@refrakt-md/html 0.8.1
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/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +49 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/page-shell.d.ts +37 -0
- package/dist/page-shell.d.ts.map +1 -0
- package/dist/page-shell.js +85 -0
- package/dist/page-shell.js.map +1 -0
- package/dist/render.d.ts +15 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +25 -0
- package/dist/render.js.map +1 -0
- package/dist/theme.d.ts +14 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +2 -0
- package/dist/theme.js.map +1 -0
- package/dist/tree-transforms.d.ts +10 -0
- package/dist/tree-transforms.d.ts.map +1 -0
- package/dist/tree-transforms.js +22 -0
- package/dist/tree-transforms.js.map +1 -0
- package/package.json +48 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side runtime for @refrakt-md/html pages.
|
|
3
|
+
*
|
|
4
|
+
* Import this module in your client bundle to initialize interactive behaviors.
|
|
5
|
+
* It reads page context from the embedded `<script id="rf-context">` element
|
|
6
|
+
* and wires up all rune and layout behaviors.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { initPage } from '@refrakt-md/html/client';
|
|
10
|
+
* initPage();
|
|
11
|
+
*
|
|
12
|
+
* For SPA-style navigation where the DOM is replaced:
|
|
13
|
+
* import { initPage } from '@refrakt-md/html/client';
|
|
14
|
+
* // Call on each page swap — returns a cleanup function
|
|
15
|
+
* const cleanup = initPage();
|
|
16
|
+
* // Before swapping: cleanup();
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Initialize all interactive behaviors for the current page.
|
|
20
|
+
*
|
|
21
|
+
* Reads context from the embedded JSON script, registers web component elements,
|
|
22
|
+
* and initializes rune and layout behaviors.
|
|
23
|
+
*
|
|
24
|
+
* Returns a cleanup function that removes all behavior event listeners.
|
|
25
|
+
*/
|
|
26
|
+
export declare function initPage(container?: HTMLElement | Document): Promise<() => void>;
|
|
27
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAkBH;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,SAAS,GAAE,WAAW,GAAG,QAAmB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAwBhG"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side runtime for @refrakt-md/html pages.
|
|
3
|
+
*
|
|
4
|
+
* Import this module in your client bundle to initialize interactive behaviors.
|
|
5
|
+
* It reads page context from the embedded `<script id="rf-context">` element
|
|
6
|
+
* and wires up all rune and layout behaviors.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { initPage } from '@refrakt-md/html/client';
|
|
10
|
+
* initPage();
|
|
11
|
+
*
|
|
12
|
+
* For SPA-style navigation where the DOM is replaced:
|
|
13
|
+
* import { initPage } from '@refrakt-md/html/client';
|
|
14
|
+
* // Call on each page swap — returns a cleanup function
|
|
15
|
+
* const cleanup = initPage();
|
|
16
|
+
* // Before swapping: cleanup();
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Initialize all interactive behaviors for the current page.
|
|
20
|
+
*
|
|
21
|
+
* Reads context from the embedded JSON script, registers web component elements,
|
|
22
|
+
* and initializes rune and layout behaviors.
|
|
23
|
+
*
|
|
24
|
+
* Returns a cleanup function that removes all behavior event listeners.
|
|
25
|
+
*/
|
|
26
|
+
export async function initPage(container = document) {
|
|
27
|
+
// Dynamic import so tree-shaking works if behaviors aren't needed
|
|
28
|
+
const { registerElements, RfContext, initRuneBehaviors, initLayoutBehaviors } = await import('@refrakt-md/behaviors');
|
|
29
|
+
// Read page context from embedded script
|
|
30
|
+
const contextEl = (container === document ? document : container).querySelector?.('#rf-context');
|
|
31
|
+
if (contextEl) {
|
|
32
|
+
try {
|
|
33
|
+
const ctx = JSON.parse(contextEl.textContent ?? '{}');
|
|
34
|
+
RfContext.pages = ctx.pages;
|
|
35
|
+
RfContext.currentUrl = ctx.currentUrl;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Context parsing failed — behaviors will work without it
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
registerElements();
|
|
42
|
+
const cleanupRunes = initRuneBehaviors(container);
|
|
43
|
+
const cleanupLayout = initLayoutBehaviors(container);
|
|
44
|
+
return () => {
|
|
45
|
+
cleanupRunes();
|
|
46
|
+
cleanupLayout();
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAkBH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,YAAoC,QAAQ;IAC1E,kEAAkE;IAClE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAEtH,yCAAyC;IACzC,MAAM,SAAS,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC;IACjG,IAAI,SAAS,EAAE,CAAC;QACf,IAAI,CAAC;YACJ,MAAM,GAAG,GAAgB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;YACnE,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC5B,SAAS,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACR,0DAA0D;QAC3D,CAAC;IACF,CAAC;IAED,gBAAgB,EAAE,CAAC;IACnB,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAwB,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,mBAAmB,CAAC,SAAwB,CAAC,CAAC;IAEpE,OAAO,GAAG,EAAE;QACX,YAAY,EAAE,CAAC;QACf,aAAa,EAAE,CAAC;IACjB,CAAC,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { HtmlTheme } from './theme.js';
|
|
2
|
+
export { renderPage } from './render.js';
|
|
3
|
+
export type { RenderPageInput } from './render.js';
|
|
4
|
+
export { renderFullPage } from './page-shell.js';
|
|
5
|
+
export type { PageShellOptions } from './page-shell.js';
|
|
6
|
+
export { applyHtmlTransforms } from './tree-transforms.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Rendering
|
|
2
|
+
export { renderPage } from './render.js';
|
|
3
|
+
// Full page shell
|
|
4
|
+
export { renderFullPage } from './page-shell.js';
|
|
5
|
+
// Tree transforms (useful for custom pipelines)
|
|
6
|
+
export { applyHtmlTransforms } from './tree-transforms.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY;AACZ,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,gDAAgD;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { RenderPageInput } from './render.js';
|
|
2
|
+
interface OgMeta {
|
|
3
|
+
title?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
image?: string;
|
|
6
|
+
type?: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
}
|
|
9
|
+
interface PageSeo {
|
|
10
|
+
jsonLd: object[];
|
|
11
|
+
og: OgMeta;
|
|
12
|
+
}
|
|
13
|
+
export interface PageShellOptions {
|
|
14
|
+
/** CSS stylesheet URLs to include in <head> */
|
|
15
|
+
stylesheets?: string[];
|
|
16
|
+
/** JavaScript URLs to include before </body> */
|
|
17
|
+
scripts?: string[];
|
|
18
|
+
/** Extra HTML to inject into <head> */
|
|
19
|
+
headExtra?: string;
|
|
20
|
+
/** HTML lang attribute (default: "en") */
|
|
21
|
+
lang?: string;
|
|
22
|
+
/** Base URL for OpenGraph canonical URLs */
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
/** SEO metadata extracted from the page */
|
|
25
|
+
seo?: PageSeo;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Render a complete HTML document from page data.
|
|
29
|
+
*
|
|
30
|
+
* Produces a full `<!DOCTYPE html>` page with:
|
|
31
|
+
* - `<head>` containing title, meta description, OG tags, JSON-LD, stylesheets
|
|
32
|
+
* - `<body>` containing the rendered page content
|
|
33
|
+
* - Script tags for behaviors
|
|
34
|
+
*/
|
|
35
|
+
export declare function renderFullPage(input: RenderPageInput, options?: PageShellOptions): string;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=page-shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-shell.d.ts","sourceRoot":"","sources":["../src/page-shell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,UAAU,MAAM;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,UAAU,OAAO;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,gBAAgB;IAChC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AAcD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CA8E7F"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { renderPage } from './render.js';
|
|
2
|
+
function escapeHtml(s) {
|
|
3
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
4
|
+
}
|
|
5
|
+
function renderMetaTag(name, content) {
|
|
6
|
+
return `<meta name="${escapeHtml(name)}" content="${escapeHtml(content)}">`;
|
|
7
|
+
}
|
|
8
|
+
function renderOgTag(property, content) {
|
|
9
|
+
return `<meta property="${escapeHtml(property)}" content="${escapeHtml(content)}">`;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Render a complete HTML document from page data.
|
|
13
|
+
*
|
|
14
|
+
* Produces a full `<!DOCTYPE html>` page with:
|
|
15
|
+
* - `<head>` containing title, meta description, OG tags, JSON-LD, stylesheets
|
|
16
|
+
* - `<body>` containing the rendered page content
|
|
17
|
+
* - Script tags for behaviors
|
|
18
|
+
*/
|
|
19
|
+
export function renderFullPage(input, options = {}) {
|
|
20
|
+
const { page } = input;
|
|
21
|
+
const { lang = 'en', stylesheets = [], scripts = [], headExtra = '', seo } = options;
|
|
22
|
+
const headParts = [];
|
|
23
|
+
headParts.push('<meta charset="utf-8">');
|
|
24
|
+
headParts.push('<meta name="viewport" content="width=device-width, initial-scale=1">');
|
|
25
|
+
// Title
|
|
26
|
+
const title = seo?.og?.title ?? page.title;
|
|
27
|
+
if (title) {
|
|
28
|
+
headParts.push(`<title>${escapeHtml(title)}</title>`);
|
|
29
|
+
headParts.push(renderOgTag('og:title', title));
|
|
30
|
+
}
|
|
31
|
+
// Description
|
|
32
|
+
const description = seo?.og?.description ?? page.frontmatter?.description;
|
|
33
|
+
if (description) {
|
|
34
|
+
headParts.push(renderMetaTag('description', description));
|
|
35
|
+
headParts.push(renderOgTag('og:description', description));
|
|
36
|
+
}
|
|
37
|
+
// OG image
|
|
38
|
+
if (seo?.og?.image) {
|
|
39
|
+
headParts.push(renderOgTag('og:image', seo.og.image));
|
|
40
|
+
headParts.push(renderMetaTag('twitter:card', 'summary_large_image'));
|
|
41
|
+
}
|
|
42
|
+
// OG URL
|
|
43
|
+
if (seo?.og?.url) {
|
|
44
|
+
headParts.push(renderOgTag('og:url', seo.og.url));
|
|
45
|
+
}
|
|
46
|
+
// OG type
|
|
47
|
+
if (seo?.og?.type) {
|
|
48
|
+
headParts.push(renderOgTag('og:type', seo.og.type));
|
|
49
|
+
}
|
|
50
|
+
// JSON-LD
|
|
51
|
+
if (seo?.jsonLd) {
|
|
52
|
+
for (const schema of seo.jsonLd) {
|
|
53
|
+
headParts.push(`<script type="application/ld+json">${JSON.stringify(schema)}</script>`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Stylesheets
|
|
57
|
+
for (const href of stylesheets) {
|
|
58
|
+
headParts.push(`<link rel="stylesheet" href="${escapeHtml(href)}">`);
|
|
59
|
+
}
|
|
60
|
+
// Extra head content
|
|
61
|
+
if (headExtra) {
|
|
62
|
+
headParts.push(headExtra);
|
|
63
|
+
}
|
|
64
|
+
// Context data for client-side behaviors
|
|
65
|
+
const contextData = JSON.stringify({
|
|
66
|
+
pages: page.pages,
|
|
67
|
+
currentUrl: page.url,
|
|
68
|
+
});
|
|
69
|
+
// Body
|
|
70
|
+
const bodyContent = renderPage(input);
|
|
71
|
+
// Scripts
|
|
72
|
+
const scriptTags = scripts.map(src => `<script src="${escapeHtml(src)}"></script>`).join('\n');
|
|
73
|
+
return `<!DOCTYPE html>
|
|
74
|
+
<html lang="${escapeHtml(lang)}">
|
|
75
|
+
<head>
|
|
76
|
+
${headParts.join('\n')}
|
|
77
|
+
</head>
|
|
78
|
+
<body>
|
|
79
|
+
${bodyContent}
|
|
80
|
+
<script type="application/json" id="rf-context">${contextData}</script>
|
|
81
|
+
${scriptTags}
|
|
82
|
+
</body>
|
|
83
|
+
</html>`;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=page-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-shell.js","sourceRoot":"","sources":["../src/page-shell.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LayoutPageData } from '@refrakt-md/transform';
|
|
2
|
+
import type { HtmlTheme } from './theme.js';
|
|
3
|
+
export interface RenderPageInput {
|
|
4
|
+
theme: HtmlTheme;
|
|
5
|
+
page: LayoutPageData;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Render a page's content to an HTML string.
|
|
9
|
+
*
|
|
10
|
+
* Applies the layout transform, HTML-specific tree transforms (table wrapping),
|
|
11
|
+
* and produces the final HTML string. Does NOT include the `<!DOCTYPE>` shell —
|
|
12
|
+
* use `renderFullPage` for that.
|
|
13
|
+
*/
|
|
14
|
+
export declare function renderPage(input: RenderPageInput): string;
|
|
15
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAiBzD"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { layoutTransform, renderToHtml, matchRouteRule } from '@refrakt-md/transform';
|
|
2
|
+
import { applyHtmlTransforms } from './tree-transforms.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render a page's content to an HTML string.
|
|
5
|
+
*
|
|
6
|
+
* Applies the layout transform, HTML-specific tree transforms (table wrapping),
|
|
7
|
+
* and produces the final HTML string. Does NOT include the `<!DOCTYPE>` shell —
|
|
8
|
+
* use `renderFullPage` for that.
|
|
9
|
+
*/
|
|
10
|
+
export function renderPage(input) {
|
|
11
|
+
const { theme, page } = input;
|
|
12
|
+
// Resolve layout from route rules
|
|
13
|
+
const layoutName = matchRouteRule(page.url, theme.manifest.routeRules ?? []);
|
|
14
|
+
const layoutConfig = theme.layouts[layoutName] ?? theme.layouts['default'];
|
|
15
|
+
if (!layoutConfig) {
|
|
16
|
+
// No layout config — render the bare renderable
|
|
17
|
+
const transformed = applyHtmlTransforms(page.renderable);
|
|
18
|
+
return renderToHtml(transformed);
|
|
19
|
+
}
|
|
20
|
+
// Apply layout transform → tree transforms → HTML
|
|
21
|
+
const tree = layoutTransform(layoutConfig, page, 'rf');
|
|
22
|
+
const transformed = applyHtmlTransforms(tree);
|
|
23
|
+
return renderToHtml(transformed);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAO3D;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAChD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAE9B,kCAAkC;IAClC,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IAC7E,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAE3E,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,gDAAgD;QAChD,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAiB,CAAC;QACzE,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAED,kDAAkD;IAClD,MAAM,IAAI,GAAG,eAAe,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAiB,CAAC;IAC9D,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ThemeManifest } from '@refrakt-md/types';
|
|
2
|
+
import type { LayoutConfig } from '@refrakt-md/transform';
|
|
3
|
+
/**
|
|
4
|
+
* Theme definition for the pure HTML adapter.
|
|
5
|
+
*
|
|
6
|
+
* Unlike SvelteTheme, this has no component registry or element overrides —
|
|
7
|
+
* all runes render through the identity transform and behaviors are handled
|
|
8
|
+
* client-side by @refrakt-md/behaviors.
|
|
9
|
+
*/
|
|
10
|
+
export interface HtmlTheme {
|
|
11
|
+
manifest: ThemeManifest;
|
|
12
|
+
layouts: Record<string, LayoutConfig>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC"}
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RendererNode } from '@refrakt-md/types';
|
|
2
|
+
/**
|
|
3
|
+
* Apply HTML-adapter-specific tree transforms before rendering.
|
|
4
|
+
*
|
|
5
|
+
* Currently:
|
|
6
|
+
* - Wraps bare `<table>` elements in `<div class="rf-table-wrapper">` to match
|
|
7
|
+
* Lumina's responsive table styling (packages/lumina/styles/elements/table.css)
|
|
8
|
+
*/
|
|
9
|
+
export declare function applyHtmlTransforms(node: RendererNode): RendererNode;
|
|
10
|
+
//# sourceMappingURL=tree-transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-transforms.d.ts","sourceRoot":"","sources":["../src/tree-transforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGrE;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAcpE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isTag, makeTag } from '@refrakt-md/transform';
|
|
2
|
+
/**
|
|
3
|
+
* Apply HTML-adapter-specific tree transforms before rendering.
|
|
4
|
+
*
|
|
5
|
+
* Currently:
|
|
6
|
+
* - Wraps bare `<table>` elements in `<div class="rf-table-wrapper">` to match
|
|
7
|
+
* Lumina's responsive table styling (packages/lumina/styles/elements/table.css)
|
|
8
|
+
*/
|
|
9
|
+
export function applyHtmlTransforms(node) {
|
|
10
|
+
if (!isTag(node))
|
|
11
|
+
return node;
|
|
12
|
+
// Recursively transform children first
|
|
13
|
+
const children = node.children.map(applyHtmlTransforms);
|
|
14
|
+
// Wrap top-level <table> elements in a wrapper div
|
|
15
|
+
if (node.name === 'table') {
|
|
16
|
+
return makeTag('div', { class: 'rf-table-wrapper' }, [
|
|
17
|
+
{ ...node, children },
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
return { ...node, children };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=tree-transforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-transforms.js","sourceRoot":"","sources":["../src/tree-transforms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAkB;IACrD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9B,uCAAuC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAExD,mDAAmD;IACnD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE;YACpD,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE;SACrB,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@refrakt-md/html",
|
|
3
|
+
"description": "Pure HTML renderer for refrakt.md content — no framework required",
|
|
4
|
+
"version": "0.8.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/refrakt-md/refrakt.git",
|
|
10
|
+
"directory": "packages/html"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./client": {
|
|
23
|
+
"types": "./dist/client.d.ts",
|
|
24
|
+
"default": "./dist/client.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@refrakt-md/transform": "0.8.1",
|
|
35
|
+
"@refrakt-md/types": "0.8.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@refrakt-md/behaviors": "0.8.1"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@refrakt-md/behaviors": "0.8.1"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"@refrakt-md/behaviors": {
|
|
45
|
+
"optional": true
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|