@diagrammo/dgmo 0.50.1 → 0.50.2
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/advanced.d.ts +6578 -0
- package/dist/advanced.js +6 -6
- package/dist/auto.d.ts +54 -0
- package/dist/auto.js +103 -103
- package/dist/auto.mjs +99 -8
- package/dist/block.d.ts +130 -0
- package/dist/block.js +13 -7
- package/dist/{charts-d3-LR6D3D7A.js → charts-d3-MUW3LTML.js} +3 -3
- package/dist/{chunk-7PQYTZMA.js → chunk-5WFIYXQ6.js} +5 -5
- package/dist/{chunk-YIA4LEX4.js → chunk-DN66GPY5.js} +74 -3
- package/dist/{chunk-VVZRV54S.js → chunk-KQ57MHRO.js} +2 -2
- package/dist/{chunk-4S52SK6G.js → chunk-QJJZSROI.js} +10 -3
- package/dist/{chunk-ZAD4HV2G.js → chunk-SVTI362O.js} +9 -9
- package/dist/{chunk-Y4RNXEAO.js → chunk-T5SHNNGP.js} +81 -1
- package/dist/{chunk-XDXNDSKO.js → chunk-XEGTMVYY.js} +4 -1
- package/dist/cli.cjs +124 -124
- package/dist/{dgmo-router-YTU3ENAX.js → dgmo-router-CE2G67FV.js} +3 -3
- package/dist/element.d.ts +62 -0
- package/dist/element.js +100 -100
- package/dist/element.mjs +99 -8
- package/dist/index.d.ts +185 -0
- package/dist/index.js +7 -5
- package/dist/{renderer-72LGR2YF.js → renderer-5KVCNMOJ.js} +2 -2
- package/dist/{renderer-PJM35LJN.js → renderer-P5ROYQGU.js} +2 -2
- package/dist/themes-PdPR1-hC.d.ts +916 -0
- package/docs/language-reference.md +5 -0
- package/gallery/fixtures/countdown-far.dgmo +2 -0
- package/package.json +1 -1
package/dist/auto.mjs
CHANGED
|
@@ -13545,6 +13545,8 @@ function parseChart(content, palette) {
|
|
|
13545
13545
|
result.solidFill = true;
|
|
13546
13546
|
} else if (firstToken === "no-title") {
|
|
13547
13547
|
result.noTitle = true;
|
|
13548
|
+
} else if (firstToken === "no-auto-y") {
|
|
13549
|
+
result.noAutoY = true;
|
|
13548
13550
|
} else if (firstToken === "fill") {
|
|
13549
13551
|
result.fill = true;
|
|
13550
13552
|
} else if (firstToken === "hole") {
|
|
@@ -13839,6 +13841,7 @@ var init_chart = __esm({
|
|
|
13839
13841
|
"orientation-horizontal",
|
|
13840
13842
|
"solid-fill",
|
|
13841
13843
|
"no-title",
|
|
13844
|
+
"no-auto-y",
|
|
13842
13845
|
"fill",
|
|
13843
13846
|
"hole"
|
|
13844
13847
|
]);
|
|
@@ -31924,7 +31927,14 @@ function renderLine(svg, chart, width, height, colors, palette, isDark, textColo
|
|
|
31924
31927
|
hi = Math.max(hi, v);
|
|
31925
31928
|
}
|
|
31926
31929
|
if (!isFinite(lo)) return [0, 1];
|
|
31927
|
-
if (
|
|
31930
|
+
if (chart.noAutoY) {
|
|
31931
|
+
if (lo > 0) lo = 0;
|
|
31932
|
+
} else {
|
|
31933
|
+
const pad3 = (hi - lo) * 0.05 || Math.abs(hi) * 0.05 || 1;
|
|
31934
|
+
const nlo = lo - pad3;
|
|
31935
|
+
lo = lo >= 0 && nlo < 0 ? 0 : nlo;
|
|
31936
|
+
hi = hi + pad3;
|
|
31937
|
+
}
|
|
31928
31938
|
if (lo === hi) hi = lo + 1;
|
|
31929
31939
|
return [lo, hi];
|
|
31930
31940
|
};
|
|
@@ -72501,6 +72511,7 @@ function haloRect(svg, x, y, w, h, rx, C) {
|
|
|
72501
72511
|
function pickBand(nowMs, resolvedMs, hasTime) {
|
|
72502
72512
|
const days = dayDelta(nowMs, resolvedMs);
|
|
72503
72513
|
if (hasTime && days <= 0) return "clock";
|
|
72514
|
+
if (days > 3 * 365) return "years";
|
|
72504
72515
|
if (days > 365) return "year";
|
|
72505
72516
|
if (days > 92) return "months";
|
|
72506
72517
|
if (days > 18) return "monthgrid";
|
|
@@ -72531,9 +72542,31 @@ function monthGridLayout(nowMs, resolvedMs, contentW) {
|
|
|
72531
72542
|
}
|
|
72532
72543
|
return { months, dim };
|
|
72533
72544
|
}
|
|
72545
|
+
function yearsLayout(nowMs, resolvedMs) {
|
|
72546
|
+
const y0 = new Date(nowMs).getFullYear();
|
|
72547
|
+
const y1 = new Date(resolvedMs).getFullYear();
|
|
72548
|
+
const d0 = Math.floor(y0 / 10) * 10;
|
|
72549
|
+
const d1 = Math.floor(y1 / 10) * 10;
|
|
72550
|
+
return { d0, d1, rows: (d1 - d0) / 10 + 1 };
|
|
72551
|
+
}
|
|
72534
72552
|
function bandHeightFor(kind, nowMs, resolvedMs, contentW) {
|
|
72535
72553
|
const clamp5 = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
|
|
72536
72554
|
switch (kind) {
|
|
72555
|
+
case "years": {
|
|
72556
|
+
const { rows } = yearsLayout(nowMs, resolvedMs);
|
|
72557
|
+
const rowGap = 11;
|
|
72558
|
+
const labW = 54;
|
|
72559
|
+
const gap = 7;
|
|
72560
|
+
const cellW = (contentW - labW - 10 * gap) / 10;
|
|
72561
|
+
let cellH = clamp5(cellW * 0.5, 26, 40);
|
|
72562
|
+
const MAX = 380;
|
|
72563
|
+
let total = rows * cellH + (rows - 1) * rowGap;
|
|
72564
|
+
if (total > MAX) {
|
|
72565
|
+
cellH = Math.max(9, (MAX - (rows - 1) * rowGap) / rows);
|
|
72566
|
+
total = rows * cellH + (rows - 1) * rowGap;
|
|
72567
|
+
}
|
|
72568
|
+
return total;
|
|
72569
|
+
}
|
|
72537
72570
|
case "year": {
|
|
72538
72571
|
const R = new Date(resolvedMs).getFullYear() - new Date(nowMs).getFullYear() + 1;
|
|
72539
72572
|
const yearW = 66;
|
|
@@ -72572,6 +72605,61 @@ function bandHeightFor(kind, nowMs, resolvedMs, contentW) {
|
|
|
72572
72605
|
return clamp5(contentW * 0.22, 125, 170);
|
|
72573
72606
|
}
|
|
72574
72607
|
}
|
|
72608
|
+
function vizYears(svg, g, nowMs, resolvedMs, C) {
|
|
72609
|
+
const now = new Date(nowMs);
|
|
72610
|
+
const ev = new Date(resolvedMs);
|
|
72611
|
+
const nowY = now.getFullYear();
|
|
72612
|
+
const evY = ev.getFullYear();
|
|
72613
|
+
const { d0, rows } = yearsLayout(nowMs, resolvedMs);
|
|
72614
|
+
const labW = 54;
|
|
72615
|
+
const gap = 7;
|
|
72616
|
+
const rowGap = 11;
|
|
72617
|
+
const rowH = (g.height - rowGap * (rows - 1)) / rows;
|
|
72618
|
+
const cellH = rowH;
|
|
72619
|
+
const cellW = (g.contentW - labW - 10 * gap) / 10;
|
|
72620
|
+
const rx = Math.min(6, Math.min(cellW, cellH) * 0.22);
|
|
72621
|
+
const showLabel = cellH >= 18 && cellW >= 22;
|
|
72622
|
+
const yrFont = Math.min(12, cellW * 0.34, cellH * 0.5);
|
|
72623
|
+
for (let r = 0; r < rows; r++) {
|
|
72624
|
+
const dec = d0 + r * 10;
|
|
72625
|
+
const ry = g.top + r * (rowH + rowGap);
|
|
72626
|
+
aText(
|
|
72627
|
+
svg,
|
|
72628
|
+
g.left + labW - 12,
|
|
72629
|
+
ry + rowH / 2,
|
|
72630
|
+
Math.min(14, rowH * 0.5),
|
|
72631
|
+
C.muted,
|
|
72632
|
+
800,
|
|
72633
|
+
"end",
|
|
72634
|
+
`${dec}s`,
|
|
72635
|
+
{ "dominant-baseline": "central" }
|
|
72636
|
+
);
|
|
72637
|
+
for (let i = 0; i < 10; i++) {
|
|
72638
|
+
const yr = dec + i;
|
|
72639
|
+
const before = yr < nowY;
|
|
72640
|
+
const isNow = yr === nowY;
|
|
72641
|
+
const isEv = yr === evY;
|
|
72642
|
+
const between = yr > nowY && yr < evY;
|
|
72643
|
+
const st = isEv ? roleStyle(C, "event") : isNow ? roleStyle(C, "today") : between ? gradStyle(C, (yr - nowY) / (evY - nowY)) : roleStyle(C, before ? "past" : "future");
|
|
72644
|
+
const x = g.left + labW + i * (cellW + gap);
|
|
72645
|
+
aRect(svg, x, ry, cellW, cellH, rx, st.fill, st.stroke, 1);
|
|
72646
|
+
if (isEv) haloRect(svg, x, ry, cellW, cellH, rx, C);
|
|
72647
|
+
if (showLabel) {
|
|
72648
|
+
aText(
|
|
72649
|
+
svg,
|
|
72650
|
+
x + cellW / 2,
|
|
72651
|
+
ry + cellH / 2,
|
|
72652
|
+
yrFont,
|
|
72653
|
+
st.text,
|
|
72654
|
+
isNow || isEv ? 800 : 650,
|
|
72655
|
+
"middle",
|
|
72656
|
+
String(yr),
|
|
72657
|
+
{ "dominant-baseline": "central" }
|
|
72658
|
+
);
|
|
72659
|
+
}
|
|
72660
|
+
}
|
|
72661
|
+
}
|
|
72662
|
+
}
|
|
72575
72663
|
function vizYear(svg, g, nowMs, resolvedMs, C) {
|
|
72576
72664
|
const now = new Date(nowMs);
|
|
72577
72665
|
const ev = new Date(resolvedMs);
|
|
@@ -73083,6 +73171,8 @@ function pad22(n) {
|
|
|
73083
73171
|
}
|
|
73084
73172
|
function drawBand2(svg, kind, g, nowMs, resolvedMs, C) {
|
|
73085
73173
|
switch (kind) {
|
|
73174
|
+
case "years":
|
|
73175
|
+
return vizYears(svg, g, nowMs, resolvedMs, C);
|
|
73086
73176
|
case "year":
|
|
73087
73177
|
return vizYear(svg, g, nowMs, resolvedMs, C);
|
|
73088
73178
|
case "months":
|
|
@@ -73762,13 +73852,13 @@ function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
|
|
|
73762
73852
|
const mainFont = 48;
|
|
73763
73853
|
const baseY = center + 16;
|
|
73764
73854
|
const capTop = baseY - mainFont * 0.7;
|
|
73765
|
-
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", contentLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", mainFont).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
73766
73855
|
const sf = 20;
|
|
73767
73856
|
const mainW = [...ts.main].reduce(
|
|
73768
|
-
(w, c) => w + mainFont * (c === ":" ? 0.
|
|
73857
|
+
(w, c) => w + mainFont * (c === ":" ? 0.334 : 0.6),
|
|
73769
73858
|
0
|
|
73770
73859
|
);
|
|
73771
73860
|
const stackX = contentLeft + mainW + 5;
|
|
73861
|
+
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", contentLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", mainFont).attr("font-weight", 600).attr("textLength", mainW).attr("lengthAdjust", "spacing").style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
73772
73862
|
g.append("text").attr("data-dgmo-clock-digital-part", "sec").attr("x", stackX).attr("y", capTop + sf * 0.72).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", sf).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(`:${ts.sec}`);
|
|
73773
73863
|
if (ts.ap)
|
|
73774
73864
|
g.append("text").attr("data-dgmo-clock-digital-part", "ap").attr("x", stackX).attr("y", baseY).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", sf).attr("font-weight", 600).text(ts.ap);
|
|
@@ -73907,13 +73997,13 @@ function drawColumns(body, parsed, now, top, geom, col) {
|
|
|
73907
73997
|
const sf = 13;
|
|
73908
73998
|
const tf = fitFont(ts.main, 44, innerW - 30, 20);
|
|
73909
73999
|
const mainW = [...ts.main].reduce(
|
|
73910
|
-
(w, c) => w + tf * (c === ":" ? 0.
|
|
74000
|
+
(w, c) => w + tf * (c === ":" ? 0.334 : 0.6),
|
|
73911
74001
|
0
|
|
73912
74002
|
);
|
|
73913
74003
|
const stackW = Math.max(estWidth(`:${ts.sec}`, sf), estWidth(ts.ap, sf));
|
|
73914
74004
|
const gLeft = cx - (mainW + 7 + stackW) / 2;
|
|
73915
74005
|
const baseY = cy + tf * 0.34;
|
|
73916
|
-
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", gLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", tf).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
74006
|
+
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", gLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", tf).attr("font-weight", 600).attr("textLength", mainW).attr("lengthAdjust", "spacing").style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
73917
74007
|
const stackX = gLeft + mainW + 7;
|
|
73918
74008
|
g.append("text").attr("data-dgmo-clock-digital-part", "sec").attr("x", stackX).attr("y", baseY - tf * 0.32).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", sf).attr("font-weight", 500).text(`:${ts.sec}`);
|
|
73919
74009
|
if (ts.ap)
|
|
@@ -81465,7 +81555,7 @@ async function render(content, options) {
|
|
|
81465
81555
|
try {
|
|
81466
81556
|
const raw = await renderDataChartD3(renderContent, theme, paletteColors);
|
|
81467
81557
|
const svg2 = injectHoverStyles(raw, chartType, { bakeHover });
|
|
81468
|
-
return { svg: svg2, diagnostics };
|
|
81558
|
+
return { svg: svg2, diagnostics, chartType: chartType ?? void 0 };
|
|
81469
81559
|
} finally {
|
|
81470
81560
|
releaseDom();
|
|
81471
81561
|
}
|
|
@@ -81506,7 +81596,7 @@ async function render(content, options) {
|
|
|
81506
81596
|
} catch {
|
|
81507
81597
|
}
|
|
81508
81598
|
}
|
|
81509
|
-
return { svg, diagnostics };
|
|
81599
|
+
return { svg, diagnostics, chartType: chartType ?? void 0 };
|
|
81510
81600
|
}
|
|
81511
81601
|
|
|
81512
81602
|
// src/countdown/ticker.ts
|
|
@@ -82714,6 +82804,7 @@ function resolveBlockOptions(opts) {
|
|
|
82714
82804
|
mode,
|
|
82715
82805
|
palette: opts.palette ?? "slate",
|
|
82716
82806
|
colorMode: opts.colorMode ?? "auto",
|
|
82807
|
+
background: opts.background ?? "auto",
|
|
82717
82808
|
showSource: opts.showSource ?? showcase,
|
|
82718
82809
|
showCopy: opts.showCopy ?? showcase,
|
|
82719
82810
|
showExpand: opts.showExpand ?? showcase,
|
|
@@ -82816,7 +82907,7 @@ var CSS = AUTO_BASE_CSS + "\n" + BLOCK_CSS + "\n" + darkScopedBlockCss(BLOCK_CSS
|
|
|
82816
82907
|
|
|
82817
82908
|
// src/auto/shared.ts
|
|
82818
82909
|
init_safe_href();
|
|
82819
|
-
var VERSION = "0.50.
|
|
82910
|
+
var VERSION = "0.50.2";
|
|
82820
82911
|
var ARIA_LABEL_MAX = 200;
|
|
82821
82912
|
var COPIED_INTERACTION_MS = 1500;
|
|
82822
82913
|
var LOG_PREFIX = "[dgmo]";
|
package/dist/block.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical stylesheet for the standard DGMO embed block (BL-114).
|
|
3
|
+
*
|
|
4
|
+
* Shipped two ways: `dist/block.css` (extracted at build time by
|
|
5
|
+
* tsup.config.ts, same regex mechanism as auto.css) for `<link>`/import
|
|
6
|
+
* consumers, and the `BLOCK_CSS` string export for embedders that inject a
|
|
7
|
+
* `<style>` tag.
|
|
8
|
+
*
|
|
9
|
+
* Dark mode keys off `[data-theme="dark"]`. Hosts with a different signal
|
|
10
|
+
* (`html.dark`, `body.theme-dark`) rewrite the selector at their build step —
|
|
11
|
+
* fumadocs-dgmo/nextra-dgmo's build-css.mjs is the reference adapter.
|
|
12
|
+
*
|
|
13
|
+
* The `.dgmo-tok-*` role colors mirror LIGHT_ROLE_STYLES (light) and
|
|
14
|
+
* NORD_ROLE_STYLES (dark) from editor/highlight-api.ts. A parity test
|
|
15
|
+
* (tests/block.test.ts) guards against drift — update both when either
|
|
16
|
+
* changes.
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT: keep this a single pure template literal — the build extracts it
|
|
19
|
+
* with a regex, so no interpolation or computed values.
|
|
20
|
+
*/
|
|
21
|
+
declare const BLOCK_CSS: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Standard DGMO embed block (BL-114) — the ONE canonical
|
|
25
|
+
* "diagram + source chrome" HTML builder shared by every embed surface:
|
|
26
|
+
* remark-dgmo (and through it the astro/docusaurus/fumadocs/nextra/vitepress
|
|
27
|
+
* wrappers), the `/auto` script-tag drop-in, `<dgmo-diagram>`, dgmo-mcp HTML
|
|
28
|
+
* reports, the marketing site, and the Obsidian plugin.
|
|
29
|
+
*
|
|
30
|
+
* Chrome contract (user-approved 2026-07-05): the diagram is the star. A slim
|
|
31
|
+
* icon toolbar sits in a reserved row below the SVG, invisible until the
|
|
32
|
+
* block is hovered/focused or the source is open. Four wordless icon
|
|
33
|
+
* buttons — `</>` toggles the hidden source panel, expand (full-screen),
|
|
34
|
+
* copy, open-in-editor. No disclosure triangle, no text labels. The toolbar
|
|
35
|
+
* IS the <summary> of a native <details>, so show/hide works with zero
|
|
36
|
+
* JavaScript; copy and expand need a small delegated click handler
|
|
37
|
+
* (remark-dgmo's `bindDgmo` is the reference — expand's lightbox helper is
|
|
38
|
+
* mirrored across every client surface, same as copy).
|
|
39
|
+
*
|
|
40
|
+
* Markup vocabulary: `figure.dgmo` (`--diagram`/`--showcase`/`--error`),
|
|
41
|
+
* `.dgmo-light`/`.dgmo-dark` (dual color-mode) or `.dgmo-svg` (single),
|
|
42
|
+
* `details.dgmo-source-wrap > summary.dgmo-toolbar`, `.dgmo-source-inner`,
|
|
43
|
+
* `pre.dgmo-pre > span.dgmo-code` with `.dgmo-tok-<role>` token spans. While
|
|
44
|
+
* the source is open the wrapper gets one shared frame (`:has()` rule) so
|
|
45
|
+
* diagram + code read as a single unit. No visible caption — `title` becomes
|
|
46
|
+
* the wrapper's aria-label. Styles ship as `BLOCK_CSS` / `dist/block.css`.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/** Default hosted editor used by "Open in editor" links. */
|
|
50
|
+
declare const EDITOR_BASE_URL = "https://online.diagrammo.app";
|
|
51
|
+
type BlockMode = 'diagram' | 'showcase';
|
|
52
|
+
/**
|
|
53
|
+
* Color-mode strategy for the emitted SVG(s).
|
|
54
|
+
* - `auto` — render twice (light + dark) and let CSS flip visibility.
|
|
55
|
+
* - `light` / `dark` / `transparent` — single render with that theme.
|
|
56
|
+
*/
|
|
57
|
+
type BlockColorMode = 'auto' | 'light' | 'dark' | 'transparent';
|
|
58
|
+
interface DgmoBlockOptions {
|
|
59
|
+
/** `diagram` (default): SVG only. `showcase`: SVG + source chrome. */
|
|
60
|
+
mode?: BlockMode;
|
|
61
|
+
/** Palette name. Default `slate`; unknown names warn + fall back. */
|
|
62
|
+
palette?: string;
|
|
63
|
+
/** Default `auto` (dual light/dark render). */
|
|
64
|
+
colorMode?: BlockColorMode;
|
|
65
|
+
/**
|
|
66
|
+
* Embed background. `auto` (default) strips the theme's opaque root
|
|
67
|
+
* background so the diagram blends into the host page — except for
|
|
68
|
+
* background-meaningful types like `map`, which stay opaque. `transparent` /
|
|
69
|
+
* `opaque` force the choice regardless of type (the embedder opt-out).
|
|
70
|
+
*/
|
|
71
|
+
background?: 'auto' | 'transparent' | 'opaque';
|
|
72
|
+
/** Default: true in showcase mode, false in diagram mode. */
|
|
73
|
+
showSource?: boolean;
|
|
74
|
+
/** Default: true in showcase mode, false in diagram mode. */
|
|
75
|
+
showCopy?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Show the expand (full-screen) toolbar button. Default: true in showcase
|
|
78
|
+
* mode, false in diagram mode. Needs the client lightbox handler to do
|
|
79
|
+
* anything (mirrored across surfaces); markup-only surfaces can omit it.
|
|
80
|
+
*/
|
|
81
|
+
showExpand?: boolean;
|
|
82
|
+
/** Default: true in showcase mode, false in diagram mode. */
|
|
83
|
+
showOpenInEditor?: boolean;
|
|
84
|
+
/** Base URL for the open-in-editor link. Default: online.diagrammo.app. */
|
|
85
|
+
editorBaseUrl?: string;
|
|
86
|
+
/** Outer wrapper element. Default `figure`. */
|
|
87
|
+
wrapper?: 'figure' | 'div';
|
|
88
|
+
/** Base class for the wrapper (styling hook). Default `dgmo`. */
|
|
89
|
+
className?: string;
|
|
90
|
+
/** Extra classes appended to every emitted wrapper (compat shims). */
|
|
91
|
+
legacyClassNames?: string[];
|
|
92
|
+
/**
|
|
93
|
+
* Accessible name for the block (`aria-label` on the wrapper). NOT rendered
|
|
94
|
+
* visually — the chart's visible title belongs in the DGMO source itself.
|
|
95
|
+
*/
|
|
96
|
+
title?: string;
|
|
97
|
+
/** Receives palette-fallback warnings. Default: console.warn. */
|
|
98
|
+
onWarn?: (message: string) => void;
|
|
99
|
+
}
|
|
100
|
+
interface DgmoBlockResult {
|
|
101
|
+
html: string;
|
|
102
|
+
diagnostics: Array<{
|
|
103
|
+
message: string;
|
|
104
|
+
line?: number;
|
|
105
|
+
severity?: string;
|
|
106
|
+
}>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Render one ```dgmo source block to the standard embed HTML. Async because
|
|
110
|
+
* it runs the full dgmo render pipeline (once per color mode).
|
|
111
|
+
*
|
|
112
|
+
* Render errors are NOT caught here — callers decide between throwing,
|
|
113
|
+
* `errorBlockHtml()`, or their own fallback.
|
|
114
|
+
*/
|
|
115
|
+
declare function renderDgmoBlock(source: string, options?: DgmoBlockOptions): Promise<DgmoBlockResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Assemble the standard block around already-rendered SVG markup. Exposed for
|
|
118
|
+
* surfaces that render through their own pipeline (e.g. dgmo-mcp's
|
|
119
|
+
* renderPipeline) but must emit the canonical chrome. `svgsHtml` must be the
|
|
120
|
+
* `.dgmo-light`+`.dgmo-dark` (or `.dgmo-svg`) wrapper divs.
|
|
121
|
+
*/
|
|
122
|
+
declare function buildDgmoBlockHtml(source: string, svgsHtml: string, options?: DgmoBlockOptions): string;
|
|
123
|
+
/**
|
|
124
|
+
* Standard error card for a block that failed to parse/render. Same shape on
|
|
125
|
+
* every surface: `.dgmo--error` with `role="alert"`, message + offending
|
|
126
|
+
* source.
|
|
127
|
+
*/
|
|
128
|
+
declare function errorBlockHtml(err: unknown, source: string, options?: Pick<DgmoBlockOptions, 'className' | 'legacyClassNames'>): string;
|
|
129
|
+
|
|
130
|
+
export { BLOCK_CSS, type BlockColorMode, type BlockMode, type DgmoBlockOptions, type DgmoBlockResult, EDITOR_BASE_URL, buildDgmoBlockHtml, errorBlockHtml, renderDgmoBlock };
|
package/dist/block.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
defaultEmbedBackground,
|
|
2
3
|
normalizeSvgForEmbed,
|
|
3
4
|
renderErrorCard
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DN66GPY5.js";
|
|
5
6
|
import {
|
|
6
7
|
encodeDiagramUrl,
|
|
7
8
|
render
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-SVTI362O.js";
|
|
9
10
|
import "./chunk-66RUL3XF.js";
|
|
10
11
|
import "./chunk-YRYKTYMQ.js";
|
|
11
12
|
import "./chunk-YYVTBZZC.js";
|
|
12
13
|
import "./chunk-HEVYAHLW.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-KQ57MHRO.js";
|
|
14
15
|
import "./chunk-Q4V4XQWV.js";
|
|
15
16
|
import "./chunk-BTUTZMPT.js";
|
|
16
17
|
import {
|
|
@@ -22,7 +23,7 @@ import "./chunk-QXKWYZNR.js";
|
|
|
22
23
|
import "./chunk-PGEGPSCZ.js";
|
|
23
24
|
import "./chunk-3UIKSPFB.js";
|
|
24
25
|
import "./chunk-BDXC7MDK.js";
|
|
25
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-QJJZSROI.js";
|
|
26
27
|
import "./chunk-HGN652MU.js";
|
|
27
28
|
import "./chunk-U6EQI3U6.js";
|
|
28
29
|
import "./chunk-7UEMZREK.js";
|
|
@@ -30,7 +31,7 @@ import "./chunk-A4GOY3PE.js";
|
|
|
30
31
|
import "./chunk-6KFWC4CO.js";
|
|
31
32
|
import "./chunk-HQCHYB5F.js";
|
|
32
33
|
import "./chunk-5LWQH6QV.js";
|
|
33
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-XEGTMVYY.js";
|
|
34
35
|
import "./chunk-I2WKW7C7.js";
|
|
35
36
|
import "./chunk-TSA237IM.js";
|
|
36
37
|
import "./chunk-6IAA2QQ2.js";
|
|
@@ -952,6 +953,7 @@ function resolveBlockOptions(opts) {
|
|
|
952
953
|
mode,
|
|
953
954
|
palette: opts.palette ?? "slate",
|
|
954
955
|
colorMode: opts.colorMode ?? "auto",
|
|
956
|
+
background: opts.background ?? "auto",
|
|
955
957
|
showSource: opts.showSource ?? showcase,
|
|
956
958
|
showCopy: opts.showCopy ?? showcase,
|
|
957
959
|
showExpand: opts.showExpand ?? showcase,
|
|
@@ -969,8 +971,10 @@ async function renderDgmoBlock(source, options = {}) {
|
|
|
969
971
|
const trimmed = source.trim();
|
|
970
972
|
const palette = resolvePaletteOrFallback(opts.palette, opts.onWarn);
|
|
971
973
|
const diagnostics = [];
|
|
974
|
+
let chartType;
|
|
972
975
|
const renderTheme = async (theme) => {
|
|
973
976
|
const r = await render(trimmed, { palette: palette.id, theme });
|
|
977
|
+
chartType = r.chartType;
|
|
974
978
|
diagnostics.push(...r.diagnostics);
|
|
975
979
|
const errors = r.diagnostics.filter((d) => d.severity === "error");
|
|
976
980
|
return errors.length ? renderErrorCard(errors, trimmed, palette, theme) : r.svg;
|
|
@@ -981,10 +985,12 @@ async function renderDgmoBlock(source, options = {}) {
|
|
|
981
985
|
renderTheme("light"),
|
|
982
986
|
renderTheme("dark")
|
|
983
987
|
]);
|
|
984
|
-
|
|
988
|
+
const background = opts.background === "auto" ? defaultEmbedBackground(chartType) : opts.background;
|
|
989
|
+
svgsHtml = `<div class="${escapeAttr(innerClasses(opts, "dgmo-light"))}">${normalizeSvgForEmbed(light, { background })}</div><div class="${escapeAttr(innerClasses(opts, "dgmo-dark"))}">${normalizeSvgForEmbed(dark, { background })}</div>`;
|
|
985
990
|
} else {
|
|
986
991
|
const svg = await renderTheme(opts.colorMode);
|
|
987
|
-
|
|
992
|
+
const background = opts.background === "auto" ? defaultEmbedBackground(chartType) : opts.background;
|
|
993
|
+
svgsHtml = `<div class="${escapeAttr(innerClasses(opts, "dgmo-svg"))}">${normalizeSvgForEmbed(svg, { background })}</div>`;
|
|
988
994
|
}
|
|
989
995
|
return { html: assembleBlock(trimmed, svgsHtml, opts), diagnostics };
|
|
990
996
|
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
D3_DATA_CHART_TYPES,
|
|
3
3
|
renderDataChartD3,
|
|
4
4
|
supportsD3DataChart
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QJJZSROI.js";
|
|
6
6
|
import "./chunk-HGN652MU.js";
|
|
7
7
|
import "./chunk-U6EQI3U6.js";
|
|
8
8
|
import "./chunk-7UEMZREK.js";
|
|
@@ -10,7 +10,7 @@ import "./chunk-A4GOY3PE.js";
|
|
|
10
10
|
import "./chunk-6KFWC4CO.js";
|
|
11
11
|
import "./chunk-HQCHYB5F.js";
|
|
12
12
|
import "./chunk-5LWQH6QV.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-XEGTMVYY.js";
|
|
14
14
|
import "./chunk-R3XI2VC7.js";
|
|
15
15
|
import "./chunk-P6T66CCZ.js";
|
|
16
16
|
import "./chunk-FJUNPCYI.js";
|
|
@@ -23,4 +23,4 @@ export {
|
|
|
23
23
|
renderDataChartD3,
|
|
24
24
|
supportsD3DataChart
|
|
25
25
|
};
|
|
26
|
-
//# sourceMappingURL=charts-d3-
|
|
26
|
+
//# sourceMappingURL=charts-d3-MUW3LTML.js.map
|
|
@@ -457,13 +457,13 @@ function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
|
|
|
457
457
|
const mainFont = 48;
|
|
458
458
|
const baseY = center + 16;
|
|
459
459
|
const capTop = baseY - mainFont * 0.7;
|
|
460
|
-
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", contentLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", mainFont).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
461
460
|
const sf = 20;
|
|
462
461
|
const mainW = [...ts.main].reduce(
|
|
463
|
-
(w, c) => w + mainFont * (c === ":" ? 0.
|
|
462
|
+
(w, c) => w + mainFont * (c === ":" ? 0.334 : 0.6),
|
|
464
463
|
0
|
|
465
464
|
);
|
|
466
465
|
const stackX = contentLeft + mainW + 5;
|
|
466
|
+
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", contentLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", mainFont).attr("font-weight", 600).attr("textLength", mainW).attr("lengthAdjust", "spacing").style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
467
467
|
g.append("text").attr("data-dgmo-clock-digital-part", "sec").attr("x", stackX).attr("y", capTop + sf * 0.72).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", sf).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(`:${ts.sec}`);
|
|
468
468
|
if (ts.ap)
|
|
469
469
|
g.append("text").attr("data-dgmo-clock-digital-part", "ap").attr("x", stackX).attr("y", baseY).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", sf).attr("font-weight", 600).text(ts.ap);
|
|
@@ -602,13 +602,13 @@ function drawColumns(body, parsed, now, top, geom, col) {
|
|
|
602
602
|
const sf = 13;
|
|
603
603
|
const tf = fitFont(ts.main, 44, innerW - 30, 20);
|
|
604
604
|
const mainW = [...ts.main].reduce(
|
|
605
|
-
(w, c) => w + tf * (c === ":" ? 0.
|
|
605
|
+
(w, c) => w + tf * (c === ":" ? 0.334 : 0.6),
|
|
606
606
|
0
|
|
607
607
|
);
|
|
608
608
|
const stackW = Math.max(estWidth(`:${ts.sec}`, sf), estWidth(ts.ap, sf));
|
|
609
609
|
const gLeft = cx - (mainW + 7 + stackW) / 2;
|
|
610
610
|
const baseY = cy + tf * 0.34;
|
|
611
|
-
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", gLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", tf).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
611
|
+
g.append("text").attr("data-dgmo-clock-digital", "").attr("data-dgmo-clock-digital-part", "main").attr("x", gLeft).attr("y", baseY).attr("fill", timeColor).attr("font-family", FONT_FAMILY).attr("font-size", tf).attr("font-weight", 600).attr("textLength", mainW).attr("lengthAdjust", "spacing").style("font-variant-numeric", "tabular-nums").text(ts.main);
|
|
612
612
|
const stackX = gLeft + mainW + 7;
|
|
613
613
|
g.append("text").attr("data-dgmo-clock-digital-part", "sec").attr("x", stackX).attr("y", baseY - tf * 0.32).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", sf).attr("font-weight", 500).text(`:${ts.sec}`);
|
|
614
614
|
if (ts.ap)
|
|
@@ -678,4 +678,4 @@ export {
|
|
|
678
678
|
renderClock,
|
|
679
679
|
renderClockForExport
|
|
680
680
|
};
|
|
681
|
-
//# sourceMappingURL=chunk-
|
|
681
|
+
//# sourceMappingURL=chunk-5WFIYXQ6.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodeDiagramUrl
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SVTI362O.js";
|
|
4
4
|
import {
|
|
5
5
|
FONT_FAMILY
|
|
6
6
|
} from "./chunk-6KFWC4CO.js";
|
|
@@ -176,8 +176,11 @@ function escapeXml(s) {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// src/utils/svg-embed.ts
|
|
179
|
-
function normalizeSvgForEmbed(input) {
|
|
179
|
+
function normalizeSvgForEmbed(input, opts = {}) {
|
|
180
180
|
let svg = input;
|
|
181
|
+
if ((opts.background ?? "transparent") === "transparent") {
|
|
182
|
+
svg = stripRootBackground(svg);
|
|
183
|
+
}
|
|
181
184
|
const rootMatch = svg.match(/<svg[^>]*>/);
|
|
182
185
|
const rootTag = rootMatch?.[0] ?? "";
|
|
183
186
|
if (rootTag && !rootTag.includes("viewBox")) {
|
|
@@ -207,6 +210,73 @@ function normalizeSvgForEmbed(input) {
|
|
|
207
210
|
svg = svg.replace(/<svg\s{2,}/g, "<svg ");
|
|
208
211
|
return svg;
|
|
209
212
|
}
|
|
213
|
+
var BG_MEANINGFUL_TYPES = /* @__PURE__ */ new Set(["map"]);
|
|
214
|
+
function defaultEmbedBackground(chartType) {
|
|
215
|
+
return chartType && BG_MEANINGFUL_TYPES.has(chartType) ? "opaque" : "transparent";
|
|
216
|
+
}
|
|
217
|
+
function stripRootBackground(svg) {
|
|
218
|
+
const rootMatch = svg.match(/<svg\b[^>]*>/);
|
|
219
|
+
if (!rootMatch) return svg;
|
|
220
|
+
const rootTag = rootMatch[0];
|
|
221
|
+
const styleMatch = rootTag.match(/style="([^"]*)"/);
|
|
222
|
+
const style = styleMatch?.[1] ?? "";
|
|
223
|
+
const bgMatch = style.match(/background:\s*([^;]+)/);
|
|
224
|
+
const bgColor = bgMatch ? normalizeColor(bgMatch[1]) : null;
|
|
225
|
+
const canvas = rootCanvas(rootTag, svg);
|
|
226
|
+
let out = svg;
|
|
227
|
+
if (bgMatch) {
|
|
228
|
+
const cleaned = style.replace(/background:\s*[^;]+;?/i, "").replace(/\s{2,}/g, " ").replace(/;\s*$/, "").trim();
|
|
229
|
+
const newRoot = (cleaned ? rootTag.replace(/style="[^"]*"/, `style="${cleaned}"`) : rootTag.replace(/\s*style="[^"]*"/, "")).replace(/<svg\s{2,}/, "<svg ");
|
|
230
|
+
out = out.replace(rootTag, newRoot);
|
|
231
|
+
}
|
|
232
|
+
if (bgColor && canvas) {
|
|
233
|
+
out = out.replace(
|
|
234
|
+
/<rect\b[^>]*?\/?>(?:\s*<\/rect>)?/g,
|
|
235
|
+
(m) => isFullCanvasFill(m, bgColor, canvas) ? "" : m
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
function isFullCanvasFill(tag, bgColor, canvas) {
|
|
241
|
+
const fm = tag.match(/\bfill="([^"]*)"/);
|
|
242
|
+
if (!fm || normalizeColor(fm[1]) !== bgColor) return false;
|
|
243
|
+
const w = numAttr(tag, "width");
|
|
244
|
+
const h = numAttr(tag, "height");
|
|
245
|
+
if (w === null || h === null) return false;
|
|
246
|
+
const x = numAttr(tag, "x") ?? 0;
|
|
247
|
+
const y = numAttr(tag, "y") ?? 0;
|
|
248
|
+
const T = 1.5;
|
|
249
|
+
return Math.abs(x) <= T && Math.abs(y) <= T && Math.abs(w - canvas.w) <= T && Math.abs(h - canvas.h) <= T;
|
|
250
|
+
}
|
|
251
|
+
function rootCanvas(rootTag, svg) {
|
|
252
|
+
const wm = rootTag.match(/\bwidth="([\d.]+)"/);
|
|
253
|
+
const hm = rootTag.match(/\bheight="([\d.]+)"/);
|
|
254
|
+
if (wm && hm) return { w: parseFloat(wm[1]), h: parseFloat(hm[1]) };
|
|
255
|
+
const vb = readViewBox(svg);
|
|
256
|
+
return vb ? { w: vb.width, h: vb.height } : null;
|
|
257
|
+
}
|
|
258
|
+
function numAttr(tag, name) {
|
|
259
|
+
const m = tag.match(new RegExp(`\\b${name}="([^"]*)"`));
|
|
260
|
+
if (!m) return null;
|
|
261
|
+
const n = parseFloat(m[1]);
|
|
262
|
+
return Number.isFinite(n) ? n : null;
|
|
263
|
+
}
|
|
264
|
+
function normalizeColor(c) {
|
|
265
|
+
const s = c.trim().toLowerCase();
|
|
266
|
+
const hex6 = s.match(/^#([0-9a-f]{6})$/);
|
|
267
|
+
if (hex6) {
|
|
268
|
+
const n = parseInt(hex6[1], 16);
|
|
269
|
+
return `${n >> 16 & 255},${n >> 8 & 255},${n & 255}`;
|
|
270
|
+
}
|
|
271
|
+
const hex3 = s.match(/^#([0-9a-f]{3})$/);
|
|
272
|
+
if (hex3) {
|
|
273
|
+
const [r, g, b] = hex3[1].split("").map((ch) => parseInt(ch + ch, 16));
|
|
274
|
+
return `${r},${g},${b}`;
|
|
275
|
+
}
|
|
276
|
+
const rgb = s.match(/^rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/);
|
|
277
|
+
if (rgb) return `${+rgb[1]},${+rgb[2]},${+rgb[3]}`;
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
210
280
|
function getEmbedSvgViewBox(svg) {
|
|
211
281
|
const tight = computeBBox(svg);
|
|
212
282
|
if (!tight || tight.width <= 0 || tight.height <= 0) return null;
|
|
@@ -334,6 +404,7 @@ function computeBBox(svg) {
|
|
|
334
404
|
export {
|
|
335
405
|
renderErrorCard,
|
|
336
406
|
normalizeSvgForEmbed,
|
|
407
|
+
defaultEmbedBackground,
|
|
337
408
|
getEmbedSvgViewBox
|
|
338
409
|
};
|
|
339
|
-
//# sourceMappingURL=chunk-
|
|
410
|
+
//# sourceMappingURL=chunk-DN66GPY5.js.map
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
parseHeatmap,
|
|
26
26
|
parseSankey,
|
|
27
27
|
parseScatter
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-XEGTMVYY.js";
|
|
29
29
|
import {
|
|
30
30
|
parseWireframe
|
|
31
31
|
} from "./chunk-I2WKW7C7.js";
|
|
@@ -2162,4 +2162,4 @@ export {
|
|
|
2162
2162
|
knownChartTypeIds,
|
|
2163
2163
|
parseDgmo
|
|
2164
2164
|
};
|
|
2165
|
-
//# sourceMappingURL=chunk-
|
|
2165
|
+
//# sourceMappingURL=chunk-KQ57MHRO.js.map
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
getSimpleChartLegendGroups,
|
|
33
33
|
parseChart,
|
|
34
34
|
parseExtendedChart
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-XEGTMVYY.js";
|
|
36
36
|
import {
|
|
37
37
|
contrastText,
|
|
38
38
|
getSegmentColors,
|
|
@@ -438,7 +438,14 @@ function renderLine(svg, chart, width, height, colors, palette, isDark, textColo
|
|
|
438
438
|
hi = Math.max(hi, v);
|
|
439
439
|
}
|
|
440
440
|
if (!isFinite(lo)) return [0, 1];
|
|
441
|
-
if (
|
|
441
|
+
if (chart.noAutoY) {
|
|
442
|
+
if (lo > 0) lo = 0;
|
|
443
|
+
} else {
|
|
444
|
+
const pad = (hi - lo) * 0.05 || Math.abs(hi) * 0.05 || 1;
|
|
445
|
+
const nlo = lo - pad;
|
|
446
|
+
lo = lo >= 0 && nlo < 0 ? 0 : nlo;
|
|
447
|
+
hi = hi + pad;
|
|
448
|
+
}
|
|
442
449
|
if (lo === hi) hi = lo + 1;
|
|
443
450
|
return [lo, hi];
|
|
444
451
|
};
|
|
@@ -1694,4 +1701,4 @@ export {
|
|
|
1694
1701
|
supportsD3DataChart,
|
|
1695
1702
|
renderDataChartD3
|
|
1696
1703
|
};
|
|
1697
|
-
//# sourceMappingURL=chunk-
|
|
1704
|
+
//# sourceMappingURL=chunk-QJJZSROI.js.map
|