@wireweave/core 2.8.0 → 3.0.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/index.cjs +534 -299
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +530 -299
- package/dist/parser.cjs +409 -284
- package/dist/parser.d.cts +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +409 -284
- package/dist/renderer.cjs +127 -17
- package/dist/renderer.d.cts +120 -7
- package/dist/renderer.d.ts +120 -7
- package/dist/renderer.js +122 -16
- package/dist/{types-CQDDIeyC.d.cts → types-hEr_afgw.d.cts} +23 -0
- package/dist/{types-CQDDIeyC.d.ts → types-hEr_afgw.d.ts} +23 -0
- package/package.json +1 -1
package/dist/renderer.cjs
CHANGED
|
@@ -28,11 +28,15 @@ __export(renderer_exports, {
|
|
|
28
28
|
generateStyles: () => generateStyles,
|
|
29
29
|
getIconData: () => getIconData,
|
|
30
30
|
getTheme: () => getTheme,
|
|
31
|
+
layoutCanvas: () => layoutCanvas,
|
|
31
32
|
lucideIcons: () => lucideIcons,
|
|
32
33
|
render: () => render,
|
|
34
|
+
renderCanvas: () => renderCanvas,
|
|
33
35
|
renderIconSvg: () => renderIconSvg,
|
|
36
|
+
renderPage: () => renderPage,
|
|
34
37
|
renderToHtml: () => renderToHtml,
|
|
35
|
-
renderToSvg: () => renderToSvg
|
|
38
|
+
renderToSvg: () => renderToSvg,
|
|
39
|
+
resolvePageDimensions: () => resolvePageDimensions
|
|
36
40
|
});
|
|
37
41
|
module.exports = __toCommonJS(renderer_exports);
|
|
38
42
|
|
|
@@ -49379,7 +49383,6 @@ function renderDropdown(node, ctx) {
|
|
|
49379
49383
|
"data-action": dropdownItem.action
|
|
49380
49384
|
};
|
|
49381
49385
|
const interactiveAttrStr = ctx.buildAttrsString(interactiveAttrs);
|
|
49382
|
-
const hrefAttr = dropdownItem.href ? ` href="${ctx.escapeHtml(dropdownItem.href)}"` : "";
|
|
49383
49386
|
const disabledAttr = dropdownItem.disabled ? ' disabled="disabled"' : "";
|
|
49384
49387
|
if (dropdownItem.href || dropdownItem.navigate) {
|
|
49385
49388
|
const href = dropdownItem.href || dropdownItem.navigate || "#";
|
|
@@ -49897,7 +49900,10 @@ var HtmlRenderer = class extends BaseRenderer {
|
|
|
49897
49900
|
const uiContent = this.renderChildren(uiChildren);
|
|
49898
49901
|
const title = node.title ? `<title>${this.escapeHtml(node.title)}</title>
|
|
49899
49902
|
` : "";
|
|
49900
|
-
const
|
|
49903
|
+
const { x: _canvasX, y: _canvasY, ...nodeWithoutCanvasPos } = node;
|
|
49904
|
+
void _canvasX;
|
|
49905
|
+
void _canvasY;
|
|
49906
|
+
const commonStyles = this.buildCommonStyles(nodeWithoutCanvasPos);
|
|
49901
49907
|
let viewportStyle = `position: relative; width: ${viewport.width}px; height: ${viewport.height}px; overflow: hidden`;
|
|
49902
49908
|
if (this.context.options.background) {
|
|
49903
49909
|
viewportStyle += `; background: ${this.context.options.background}`;
|
|
@@ -50316,8 +50322,99 @@ function createHtmlRenderer(options) {
|
|
|
50316
50322
|
return new HtmlRenderer(options);
|
|
50317
50323
|
}
|
|
50318
50324
|
|
|
50325
|
+
// src/renderer/page-renderer.ts
|
|
50326
|
+
function renderPage(page, options = {}) {
|
|
50327
|
+
const renderer = new HtmlRenderer(options);
|
|
50328
|
+
const { html, css } = renderer.render({
|
|
50329
|
+
type: "Document",
|
|
50330
|
+
children: [page]
|
|
50331
|
+
});
|
|
50332
|
+
const { width, height } = resolvePageDimensions(page);
|
|
50333
|
+
return { html, css, width, height };
|
|
50334
|
+
}
|
|
50335
|
+
function resolvePageDimensions(page) {
|
|
50336
|
+
const pageAny = page;
|
|
50337
|
+
const explicitW = page.w ?? pageAny.width;
|
|
50338
|
+
const explicitH = page.h ?? pageAny.height;
|
|
50339
|
+
if (typeof explicitW === "number" && typeof explicitH === "number") {
|
|
50340
|
+
return { width: explicitW, height: explicitH };
|
|
50341
|
+
}
|
|
50342
|
+
const viewport = resolveViewport(page.viewport, page.device);
|
|
50343
|
+
return { width: viewport.width, height: viewport.height };
|
|
50344
|
+
}
|
|
50345
|
+
|
|
50346
|
+
// src/renderer/canvas-renderer.ts
|
|
50347
|
+
var DEFAULT_GAP = 64;
|
|
50348
|
+
var DEFAULT_PREFIX = "wf";
|
|
50349
|
+
function layoutCanvas(pages, gap = DEFAULT_GAP) {
|
|
50350
|
+
const placed = [];
|
|
50351
|
+
let cursorX = 0;
|
|
50352
|
+
let maxRight = 0;
|
|
50353
|
+
let maxBottom = 0;
|
|
50354
|
+
for (const page of pages) {
|
|
50355
|
+
const { width, height } = resolvePageDimensions(page);
|
|
50356
|
+
const explicitX = typeof page.x === "number" ? page.x : void 0;
|
|
50357
|
+
const explicitY = typeof page.y === "number" ? page.y : void 0;
|
|
50358
|
+
const x = explicitX ?? cursorX;
|
|
50359
|
+
const y = explicitY ?? 0;
|
|
50360
|
+
placed.push({ page, x, y, w: width, h: height });
|
|
50361
|
+
if (explicitX === void 0) {
|
|
50362
|
+
cursorX = x + width + gap;
|
|
50363
|
+
}
|
|
50364
|
+
maxRight = Math.max(maxRight, x + width);
|
|
50365
|
+
maxBottom = Math.max(maxBottom, y + height);
|
|
50366
|
+
}
|
|
50367
|
+
return { placed, width: maxRight, height: maxBottom };
|
|
50368
|
+
}
|
|
50369
|
+
function renderCanvas(doc, options = {}) {
|
|
50370
|
+
const gap = options.gap ?? DEFAULT_GAP;
|
|
50371
|
+
const prefix = options.classPrefix ?? DEFAULT_PREFIX;
|
|
50372
|
+
const includeStyles = options.includeStyles !== false;
|
|
50373
|
+
const theme = options.theme === "dark" ? darkTheme : defaultTheme;
|
|
50374
|
+
const css = includeStyles ? generateStyles(theme, prefix) : "";
|
|
50375
|
+
if (doc.children.length === 0) {
|
|
50376
|
+
return {
|
|
50377
|
+
html: `<div class="${prefix}-canvas" data-empty="true"></div>`,
|
|
50378
|
+
css,
|
|
50379
|
+
width: 0,
|
|
50380
|
+
height: 0
|
|
50381
|
+
};
|
|
50382
|
+
}
|
|
50383
|
+
const { placed, width, height } = layoutCanvas(doc.children, gap);
|
|
50384
|
+
const pageRenderer = new HtmlRenderer({ ...options, includeStyles: false });
|
|
50385
|
+
const boards = placed.map((p) => {
|
|
50386
|
+
const { html: pageHtml } = pageRenderer.render({
|
|
50387
|
+
type: "Document",
|
|
50388
|
+
children: [p.page]
|
|
50389
|
+
});
|
|
50390
|
+
return wrapBoard(pageHtml, p, prefix);
|
|
50391
|
+
}).join("\n");
|
|
50392
|
+
const canvasStyle = `position: relative; width: ${width}px; height: ${height}px;`;
|
|
50393
|
+
const html = `<div class="${prefix}-canvas" style="${canvasStyle}" data-page-count="${placed.length}">
|
|
50394
|
+
${boards}
|
|
50395
|
+
</div>`;
|
|
50396
|
+
return { html, css, width, height };
|
|
50397
|
+
}
|
|
50398
|
+
function wrapBoard(pageHtml, placed, prefix) {
|
|
50399
|
+
const { x, y, w, h, page } = placed;
|
|
50400
|
+
const positionStyle = `position: absolute; left: ${x}px; top: ${y}px; width: ${w}px; height: ${h}px;`;
|
|
50401
|
+
const titleAttr = page.title ? ` data-page-title="${escapeAttr(page.title)}"` : "";
|
|
50402
|
+
const dataAttrs = ` data-page-x="${x}" data-page-y="${y}" data-page-w="${w}" data-page-h="${h}"${titleAttr}`;
|
|
50403
|
+
return `<div class="${prefix}-canvas-board" style="${positionStyle}"${dataAttrs}>
|
|
50404
|
+
${pageHtml}
|
|
50405
|
+
</div>`;
|
|
50406
|
+
}
|
|
50407
|
+
function escapeAttr(s) {
|
|
50408
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
50409
|
+
}
|
|
50410
|
+
|
|
50319
50411
|
// src/renderer/index.ts
|
|
50320
50412
|
function render(document, options = {}) {
|
|
50413
|
+
const isMultiPage = document.children.length > 1;
|
|
50414
|
+
if (isMultiPage) {
|
|
50415
|
+
const result = renderCanvas(document, options);
|
|
50416
|
+
return { html: result.html, css: result.css };
|
|
50417
|
+
}
|
|
50321
50418
|
const renderer = createHtmlRenderer(options);
|
|
50322
50419
|
return renderer.render(document);
|
|
50323
50420
|
}
|
|
@@ -50353,24 +50450,33 @@ ${html}
|
|
|
50353
50450
|
</html>`;
|
|
50354
50451
|
}
|
|
50355
50452
|
function renderToSvg(document, options = {}) {
|
|
50356
|
-
const
|
|
50453
|
+
const isMultiPage = document.children.length > 1;
|
|
50357
50454
|
let width = options.width ?? 800;
|
|
50358
50455
|
let height = options.height ?? 600;
|
|
50359
|
-
|
|
50360
|
-
|
|
50361
|
-
|
|
50362
|
-
const
|
|
50363
|
-
|
|
50364
|
-
|
|
50365
|
-
|
|
50366
|
-
|
|
50367
|
-
|
|
50368
|
-
|
|
50369
|
-
|
|
50456
|
+
let html;
|
|
50457
|
+
let css;
|
|
50458
|
+
if (isMultiPage) {
|
|
50459
|
+
const canvas = renderCanvas(document, {
|
|
50460
|
+
theme: options.theme ?? "light"
|
|
50461
|
+
});
|
|
50462
|
+
if (options.width === void 0 && options.height === void 0) {
|
|
50463
|
+
width = canvas.width;
|
|
50464
|
+
height = canvas.height;
|
|
50465
|
+
}
|
|
50466
|
+
html = canvas.html;
|
|
50467
|
+
css = canvas.css;
|
|
50468
|
+
} else {
|
|
50469
|
+
const firstPage = document.children[0];
|
|
50470
|
+
if (firstPage && options.width === void 0 && options.height === void 0) {
|
|
50471
|
+
const dims = resolvePageDimensions(firstPage);
|
|
50472
|
+
width = dims.width;
|
|
50473
|
+
height = dims.height;
|
|
50370
50474
|
}
|
|
50475
|
+
const result = render(document, { theme: options.theme ?? "light" });
|
|
50476
|
+
html = result.html;
|
|
50477
|
+
css = result.css;
|
|
50371
50478
|
}
|
|
50372
50479
|
const background = options.background ?? "#ffffff";
|
|
50373
|
-
const { html, css } = render(document, { theme: options.theme ?? "light" });
|
|
50374
50480
|
const svg = `<?xml version="1.0" encoding="UTF-8"?>
|
|
50375
50481
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
50376
50482
|
viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
|
|
@@ -50404,11 +50510,15 @@ ${css}
|
|
|
50404
50510
|
generateStyles,
|
|
50405
50511
|
getIconData,
|
|
50406
50512
|
getTheme,
|
|
50513
|
+
layoutCanvas,
|
|
50407
50514
|
lucideIcons,
|
|
50408
50515
|
render,
|
|
50516
|
+
renderCanvas,
|
|
50409
50517
|
renderIconSvg,
|
|
50518
|
+
renderPage,
|
|
50410
50519
|
renderToHtml,
|
|
50411
|
-
renderToSvg
|
|
50520
|
+
renderToSvg,
|
|
50521
|
+
resolvePageDimensions
|
|
50412
50522
|
});
|
|
50413
50523
|
/**
|
|
50414
50524
|
* Lucide Icons Data
|
package/dist/renderer.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-
|
|
1
|
+
import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-hEr_afgw.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Renderer type definitions for wireweave
|
|
@@ -25,6 +25,25 @@ interface RenderResult {
|
|
|
25
25
|
/** Generated CSS styles */
|
|
26
26
|
css: string;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Result of rendering a single page in isolation (`renderPage`).
|
|
30
|
+
* Carries the resolved pixel dimensions so callers (export pipelines, hosts)
|
|
31
|
+
* can size their wrapper without re-resolving viewport/device themselves.
|
|
32
|
+
*/
|
|
33
|
+
interface PageRenderResult extends RenderResult {
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
}
|
|
37
|
+
interface CanvasOptions extends RenderOptions {
|
|
38
|
+
/** Gap between auto-laid-out pages, in pixels. Default `64`. */
|
|
39
|
+
gap?: number;
|
|
40
|
+
}
|
|
41
|
+
interface CanvasRenderResult extends RenderResult {
|
|
42
|
+
/** Total canvas width — bounding box of all pages. */
|
|
43
|
+
width: number;
|
|
44
|
+
/** Total canvas height — bounding box of all pages. */
|
|
45
|
+
height: number;
|
|
46
|
+
}
|
|
28
47
|
interface SvgRenderOptions {
|
|
29
48
|
/** Width of the SVG viewport */
|
|
30
49
|
width?: number;
|
|
@@ -351,6 +370,90 @@ declare function generateStyles(theme: ThemeConfig, prefix?: string): string;
|
|
|
351
370
|
*/
|
|
352
371
|
declare function generateComponentStyles(_theme: ThemeConfig, prefix?: string): string;
|
|
353
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Page renderer — single-Page primitive.
|
|
375
|
+
*
|
|
376
|
+
* `renderPage` is the *pure* unit of this renderer: its output depends only
|
|
377
|
+
* on the page itself, never on sibling pages or canvas-level options. This
|
|
378
|
+
* is what export pipelines (1 page = 1 file) consume, and it is also the
|
|
379
|
+
* building block `renderCanvas` composes when laying multiple pages out.
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Render a single page to self-contained HTML + CSS.
|
|
384
|
+
*
|
|
385
|
+
* The page's HTML output is identical to what `render(document)` produces
|
|
386
|
+
* for a document containing only this page — we route through `HtmlRenderer`
|
|
387
|
+
* so the existing renderer pipeline (themes, prefix, indentation, minify)
|
|
388
|
+
* applies uniformly.
|
|
389
|
+
*/
|
|
390
|
+
declare function renderPage(page: PageNode, options?: RenderOptions): PageRenderResult;
|
|
391
|
+
/**
|
|
392
|
+
* Resolve a page's pixel dimensions from explicit `w`/`h` or viewport/device.
|
|
393
|
+
*
|
|
394
|
+
* Mirrors the precedence used inside `HtmlRenderer.renderPage`:
|
|
395
|
+
* 1. Explicit numeric `w` and `h` both set → use them.
|
|
396
|
+
* 2. Otherwise resolve via viewport string / device preset.
|
|
397
|
+
*
|
|
398
|
+
* Non-numeric `w`/`h` (e.g. keyword `'full'` or `ValueWithUnit`) fall through
|
|
399
|
+
* to the viewport — those are layout-internal hints, not canvas dimensions.
|
|
400
|
+
*/
|
|
401
|
+
declare function resolvePageDimensions(page: PageNode): {
|
|
402
|
+
width: number;
|
|
403
|
+
height: number;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Canvas renderer — multi-page composition.
|
|
408
|
+
*
|
|
409
|
+
* `renderCanvas` lays out one or more pages on a single bounded canvas. The
|
|
410
|
+
* DSL stays page-centric — coordinates come from each page's optional
|
|
411
|
+
* `at(x, y)` attribute (resolved into `Page.x` / `Page.y` by the parser).
|
|
412
|
+
* Pages without coordinates auto-flow horizontally with `gap` between them.
|
|
413
|
+
*
|
|
414
|
+
* Output is intentionally minimal: a bounded `<div class="wf-canvas">` of the
|
|
415
|
+
* exact layout extent, containing absolutely-positioned `<div class="wf-canvas-board">`
|
|
416
|
+
* wrappers around each page's HTML. No chrome, no decoration, no grid, no
|
|
417
|
+
* labels. Hosts (dashboard editor, markdown plugin, VSCode preview) wrap this
|
|
418
|
+
* output in their own viewport / grid / pan-zoom layers.
|
|
419
|
+
*
|
|
420
|
+
* `layoutCanvas` is exposed as a pure utility so hosts that want to compose
|
|
421
|
+
* the canvas DOM themselves can reuse the placement math.
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
interface PlacedPage {
|
|
425
|
+
page: PageNode;
|
|
426
|
+
x: number;
|
|
427
|
+
y: number;
|
|
428
|
+
w: number;
|
|
429
|
+
h: number;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Compute each page's position on the canvas and the bounding canvas size.
|
|
433
|
+
*
|
|
434
|
+
* Per-page mode:
|
|
435
|
+
* - `Page.x` / `Page.y` set → placed at exactly those coordinates.
|
|
436
|
+
* - Either missing → auto-flow: continues from the running cursor in a
|
|
437
|
+
* single horizontal row, advancing by `width + gap` after each
|
|
438
|
+
* auto-placed page. The cursor is unaffected by explicitly-placed pages.
|
|
439
|
+
*
|
|
440
|
+
* Mixed documents are allowed (ux-rules will warn) but explicit pages may
|
|
441
|
+
* overlap auto pages — that is the author's responsibility.
|
|
442
|
+
*/
|
|
443
|
+
declare function layoutCanvas(pages: PageNode[], gap?: number): {
|
|
444
|
+
placed: PlacedPage[];
|
|
445
|
+
width: number;
|
|
446
|
+
height: number;
|
|
447
|
+
};
|
|
448
|
+
/**
|
|
449
|
+
* Render a multi-page document to a single bounded canvas of HTML + CSS.
|
|
450
|
+
*
|
|
451
|
+
* Output: `<div class="wf-canvas" style="width:Wpx; height:Hpx; position:relative">`
|
|
452
|
+
* containing one `<div class="wf-canvas-board">` per page, absolutely
|
|
453
|
+
* positioned at the layout coordinates.
|
|
454
|
+
*/
|
|
455
|
+
declare function renderCanvas(doc: WireframeDocument, options?: CanvasOptions): CanvasRenderResult;
|
|
456
|
+
|
|
354
457
|
/**
|
|
355
458
|
* Lucide Icons Data
|
|
356
459
|
*
|
|
@@ -388,13 +491,19 @@ strokeWidth?: number, className?: string, styleAttr?: string): string;
|
|
|
388
491
|
*/
|
|
389
492
|
|
|
390
493
|
/**
|
|
391
|
-
* Render AST to HTML and CSS
|
|
494
|
+
* Render AST to HTML and CSS.
|
|
392
495
|
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
496
|
+
* Two modes, decided automatically by page count:
|
|
497
|
+
* 1. Multiple pages → canvas mode (bounded layout, absolutely-positioned
|
|
498
|
+
* boards). Hosts wrap this in their own viewport / grid / pan-zoom layer.
|
|
499
|
+
* 2. Single page → legacy mode (page only, no canvas wrapper) for
|
|
500
|
+
* backward compatibility with single-page consumers (markdown-plugin,
|
|
501
|
+
* dashboard previews, vscode-extension).
|
|
502
|
+
*
|
|
503
|
+
* Use `renderPage(page)` for explicit single-page export, or
|
|
504
|
+
* `renderCanvas(doc)` for explicit multi-page composition.
|
|
396
505
|
*/
|
|
397
|
-
declare function render(document: WireframeDocument, options?: RenderOptions): RenderResult;
|
|
506
|
+
declare function render(document: WireframeDocument, options?: RenderOptions | CanvasOptions): RenderResult;
|
|
398
507
|
/**
|
|
399
508
|
* Render AST to standalone HTML with embedded CSS
|
|
400
509
|
*
|
|
@@ -409,10 +518,14 @@ declare function renderToHtml(document: WireframeDocument, options?: RenderOptio
|
|
|
409
518
|
* This approach embeds HTML+CSS inside SVG using foreignObject,
|
|
410
519
|
* which allows CSS flexbox/grid layouts to work properly.
|
|
411
520
|
*
|
|
521
|
+
* Multi-page documents are auto-rendered as a bounded canvas, with the
|
|
522
|
+
* SVG viewBox sized to the canvas bounding box. Single-page documents
|
|
523
|
+
* keep their legacy single-page sizing.
|
|
524
|
+
*
|
|
412
525
|
* @param document - Parsed wireframe document
|
|
413
526
|
* @param options - SVG render options
|
|
414
527
|
* @returns Object containing SVG string and dimensions
|
|
415
528
|
*/
|
|
416
529
|
declare function renderToSvg(document: WireframeDocument, options?: SvgRenderOptions): SvgRenderResult;
|
|
417
530
|
|
|
418
|
-
export { HtmlRenderer, type IconData, type IconElement, type RenderContext, type RenderOptions, type RenderResult, type SvgRenderOptions, type SvgRenderResult, type ThemeColors, type ThemeConfig, createHtmlRenderer, darkTheme, defaultTheme, generateComponentStyles, generateStyles, getIconData, getTheme, lucideIcons, render, renderIconSvg, renderToHtml, renderToSvg };
|
|
531
|
+
export { type CanvasOptions, type CanvasRenderResult, HtmlRenderer, type IconData, type IconElement, type PageRenderResult, type PlacedPage, type RenderContext, type RenderOptions, type RenderResult, type SvgRenderOptions, type SvgRenderResult, type ThemeColors, type ThemeConfig, createHtmlRenderer, darkTheme, defaultTheme, generateComponentStyles, generateStyles, getIconData, getTheme, layoutCanvas, lucideIcons, render, renderCanvas, renderIconSvg, renderPage, renderToHtml, renderToSvg, resolvePageDimensions };
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-
|
|
1
|
+
import { a1 as WireframeDocument, A as AnyNode, P as PageNode } from './types-hEr_afgw.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Renderer type definitions for wireweave
|
|
@@ -25,6 +25,25 @@ interface RenderResult {
|
|
|
25
25
|
/** Generated CSS styles */
|
|
26
26
|
css: string;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Result of rendering a single page in isolation (`renderPage`).
|
|
30
|
+
* Carries the resolved pixel dimensions so callers (export pipelines, hosts)
|
|
31
|
+
* can size their wrapper without re-resolving viewport/device themselves.
|
|
32
|
+
*/
|
|
33
|
+
interface PageRenderResult extends RenderResult {
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
}
|
|
37
|
+
interface CanvasOptions extends RenderOptions {
|
|
38
|
+
/** Gap between auto-laid-out pages, in pixels. Default `64`. */
|
|
39
|
+
gap?: number;
|
|
40
|
+
}
|
|
41
|
+
interface CanvasRenderResult extends RenderResult {
|
|
42
|
+
/** Total canvas width — bounding box of all pages. */
|
|
43
|
+
width: number;
|
|
44
|
+
/** Total canvas height — bounding box of all pages. */
|
|
45
|
+
height: number;
|
|
46
|
+
}
|
|
28
47
|
interface SvgRenderOptions {
|
|
29
48
|
/** Width of the SVG viewport */
|
|
30
49
|
width?: number;
|
|
@@ -351,6 +370,90 @@ declare function generateStyles(theme: ThemeConfig, prefix?: string): string;
|
|
|
351
370
|
*/
|
|
352
371
|
declare function generateComponentStyles(_theme: ThemeConfig, prefix?: string): string;
|
|
353
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Page renderer — single-Page primitive.
|
|
375
|
+
*
|
|
376
|
+
* `renderPage` is the *pure* unit of this renderer: its output depends only
|
|
377
|
+
* on the page itself, never on sibling pages or canvas-level options. This
|
|
378
|
+
* is what export pipelines (1 page = 1 file) consume, and it is also the
|
|
379
|
+
* building block `renderCanvas` composes when laying multiple pages out.
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Render a single page to self-contained HTML + CSS.
|
|
384
|
+
*
|
|
385
|
+
* The page's HTML output is identical to what `render(document)` produces
|
|
386
|
+
* for a document containing only this page — we route through `HtmlRenderer`
|
|
387
|
+
* so the existing renderer pipeline (themes, prefix, indentation, minify)
|
|
388
|
+
* applies uniformly.
|
|
389
|
+
*/
|
|
390
|
+
declare function renderPage(page: PageNode, options?: RenderOptions): PageRenderResult;
|
|
391
|
+
/**
|
|
392
|
+
* Resolve a page's pixel dimensions from explicit `w`/`h` or viewport/device.
|
|
393
|
+
*
|
|
394
|
+
* Mirrors the precedence used inside `HtmlRenderer.renderPage`:
|
|
395
|
+
* 1. Explicit numeric `w` and `h` both set → use them.
|
|
396
|
+
* 2. Otherwise resolve via viewport string / device preset.
|
|
397
|
+
*
|
|
398
|
+
* Non-numeric `w`/`h` (e.g. keyword `'full'` or `ValueWithUnit`) fall through
|
|
399
|
+
* to the viewport — those are layout-internal hints, not canvas dimensions.
|
|
400
|
+
*/
|
|
401
|
+
declare function resolvePageDimensions(page: PageNode): {
|
|
402
|
+
width: number;
|
|
403
|
+
height: number;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Canvas renderer — multi-page composition.
|
|
408
|
+
*
|
|
409
|
+
* `renderCanvas` lays out one or more pages on a single bounded canvas. The
|
|
410
|
+
* DSL stays page-centric — coordinates come from each page's optional
|
|
411
|
+
* `at(x, y)` attribute (resolved into `Page.x` / `Page.y` by the parser).
|
|
412
|
+
* Pages without coordinates auto-flow horizontally with `gap` between them.
|
|
413
|
+
*
|
|
414
|
+
* Output is intentionally minimal: a bounded `<div class="wf-canvas">` of the
|
|
415
|
+
* exact layout extent, containing absolutely-positioned `<div class="wf-canvas-board">`
|
|
416
|
+
* wrappers around each page's HTML. No chrome, no decoration, no grid, no
|
|
417
|
+
* labels. Hosts (dashboard editor, markdown plugin, VSCode preview) wrap this
|
|
418
|
+
* output in their own viewport / grid / pan-zoom layers.
|
|
419
|
+
*
|
|
420
|
+
* `layoutCanvas` is exposed as a pure utility so hosts that want to compose
|
|
421
|
+
* the canvas DOM themselves can reuse the placement math.
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
interface PlacedPage {
|
|
425
|
+
page: PageNode;
|
|
426
|
+
x: number;
|
|
427
|
+
y: number;
|
|
428
|
+
w: number;
|
|
429
|
+
h: number;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Compute each page's position on the canvas and the bounding canvas size.
|
|
433
|
+
*
|
|
434
|
+
* Per-page mode:
|
|
435
|
+
* - `Page.x` / `Page.y` set → placed at exactly those coordinates.
|
|
436
|
+
* - Either missing → auto-flow: continues from the running cursor in a
|
|
437
|
+
* single horizontal row, advancing by `width + gap` after each
|
|
438
|
+
* auto-placed page. The cursor is unaffected by explicitly-placed pages.
|
|
439
|
+
*
|
|
440
|
+
* Mixed documents are allowed (ux-rules will warn) but explicit pages may
|
|
441
|
+
* overlap auto pages — that is the author's responsibility.
|
|
442
|
+
*/
|
|
443
|
+
declare function layoutCanvas(pages: PageNode[], gap?: number): {
|
|
444
|
+
placed: PlacedPage[];
|
|
445
|
+
width: number;
|
|
446
|
+
height: number;
|
|
447
|
+
};
|
|
448
|
+
/**
|
|
449
|
+
* Render a multi-page document to a single bounded canvas of HTML + CSS.
|
|
450
|
+
*
|
|
451
|
+
* Output: `<div class="wf-canvas" style="width:Wpx; height:Hpx; position:relative">`
|
|
452
|
+
* containing one `<div class="wf-canvas-board">` per page, absolutely
|
|
453
|
+
* positioned at the layout coordinates.
|
|
454
|
+
*/
|
|
455
|
+
declare function renderCanvas(doc: WireframeDocument, options?: CanvasOptions): CanvasRenderResult;
|
|
456
|
+
|
|
354
457
|
/**
|
|
355
458
|
* Lucide Icons Data
|
|
356
459
|
*
|
|
@@ -388,13 +491,19 @@ strokeWidth?: number, className?: string, styleAttr?: string): string;
|
|
|
388
491
|
*/
|
|
389
492
|
|
|
390
493
|
/**
|
|
391
|
-
* Render AST to HTML and CSS
|
|
494
|
+
* Render AST to HTML and CSS.
|
|
392
495
|
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
496
|
+
* Two modes, decided automatically by page count:
|
|
497
|
+
* 1. Multiple pages → canvas mode (bounded layout, absolutely-positioned
|
|
498
|
+
* boards). Hosts wrap this in their own viewport / grid / pan-zoom layer.
|
|
499
|
+
* 2. Single page → legacy mode (page only, no canvas wrapper) for
|
|
500
|
+
* backward compatibility with single-page consumers (markdown-plugin,
|
|
501
|
+
* dashboard previews, vscode-extension).
|
|
502
|
+
*
|
|
503
|
+
* Use `renderPage(page)` for explicit single-page export, or
|
|
504
|
+
* `renderCanvas(doc)` for explicit multi-page composition.
|
|
396
505
|
*/
|
|
397
|
-
declare function render(document: WireframeDocument, options?: RenderOptions): RenderResult;
|
|
506
|
+
declare function render(document: WireframeDocument, options?: RenderOptions | CanvasOptions): RenderResult;
|
|
398
507
|
/**
|
|
399
508
|
* Render AST to standalone HTML with embedded CSS
|
|
400
509
|
*
|
|
@@ -409,10 +518,14 @@ declare function renderToHtml(document: WireframeDocument, options?: RenderOptio
|
|
|
409
518
|
* This approach embeds HTML+CSS inside SVG using foreignObject,
|
|
410
519
|
* which allows CSS flexbox/grid layouts to work properly.
|
|
411
520
|
*
|
|
521
|
+
* Multi-page documents are auto-rendered as a bounded canvas, with the
|
|
522
|
+
* SVG viewBox sized to the canvas bounding box. Single-page documents
|
|
523
|
+
* keep their legacy single-page sizing.
|
|
524
|
+
*
|
|
412
525
|
* @param document - Parsed wireframe document
|
|
413
526
|
* @param options - SVG render options
|
|
414
527
|
* @returns Object containing SVG string and dimensions
|
|
415
528
|
*/
|
|
416
529
|
declare function renderToSvg(document: WireframeDocument, options?: SvgRenderOptions): SvgRenderResult;
|
|
417
530
|
|
|
418
|
-
export { HtmlRenderer, type IconData, type IconElement, type RenderContext, type RenderOptions, type RenderResult, type SvgRenderOptions, type SvgRenderResult, type ThemeColors, type ThemeConfig, createHtmlRenderer, darkTheme, defaultTheme, generateComponentStyles, generateStyles, getIconData, getTheme, lucideIcons, render, renderIconSvg, renderToHtml, renderToSvg };
|
|
531
|
+
export { type CanvasOptions, type CanvasRenderResult, HtmlRenderer, type IconData, type IconElement, type PageRenderResult, type PlacedPage, type RenderContext, type RenderOptions, type RenderResult, type SvgRenderOptions, type SvgRenderResult, type ThemeColors, type ThemeConfig, createHtmlRenderer, darkTheme, defaultTheme, generateComponentStyles, generateStyles, getIconData, getTheme, layoutCanvas, lucideIcons, render, renderCanvas, renderIconSvg, renderPage, renderToHtml, renderToSvg, resolvePageDimensions };
|