mviz 1.4.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/README.md +174 -0
- package/dist/charts/area.d.ts +14 -0
- package/dist/charts/area.d.ts.map +1 -0
- package/dist/charts/area.js +137 -0
- package/dist/charts/area.js.map +1 -0
- package/dist/charts/bar.d.ts +14 -0
- package/dist/charts/bar.d.ts.map +1 -0
- package/dist/charts/bar.js +191 -0
- package/dist/charts/bar.js.map +1 -0
- package/dist/charts/boxplot.d.ts +14 -0
- package/dist/charts/boxplot.d.ts.map +1 -0
- package/dist/charts/boxplot.js +79 -0
- package/dist/charts/boxplot.js.map +1 -0
- package/dist/charts/bubble.d.ts +14 -0
- package/dist/charts/bubble.d.ts.map +1 -0
- package/dist/charts/bubble.js +127 -0
- package/dist/charts/bubble.js.map +1 -0
- package/dist/charts/calendar.d.ts +14 -0
- package/dist/charts/calendar.d.ts.map +1 -0
- package/dist/charts/calendar.js +94 -0
- package/dist/charts/calendar.js.map +1 -0
- package/dist/charts/combo.d.ts +14 -0
- package/dist/charts/combo.d.ts.map +1 -0
- package/dist/charts/combo.js +163 -0
- package/dist/charts/combo.js.map +1 -0
- package/dist/charts/dumbbell.d.ts +17 -0
- package/dist/charts/dumbbell.d.ts.map +1 -0
- package/dist/charts/dumbbell.js +368 -0
- package/dist/charts/dumbbell.js.map +1 -0
- package/dist/charts/funnel.d.ts +14 -0
- package/dist/charts/funnel.d.ts.map +1 -0
- package/dist/charts/funnel.js +145 -0
- package/dist/charts/funnel.js.map +1 -0
- package/dist/charts/heatmap.d.ts +14 -0
- package/dist/charts/heatmap.d.ts.map +1 -0
- package/dist/charts/heatmap.js +202 -0
- package/dist/charts/heatmap.js.map +1 -0
- package/dist/charts/histogram.d.ts +14 -0
- package/dist/charts/histogram.d.ts.map +1 -0
- package/dist/charts/histogram.js +103 -0
- package/dist/charts/histogram.js.map +1 -0
- package/dist/charts/index.d.ts +40 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +42 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/line.d.ts +14 -0
- package/dist/charts/line.d.ts.map +1 -0
- package/dist/charts/line.js +134 -0
- package/dist/charts/line.js.map +1 -0
- package/dist/charts/pie.d.ts +14 -0
- package/dist/charts/pie.d.ts.map +1 -0
- package/dist/charts/pie.js +75 -0
- package/dist/charts/pie.js.map +1 -0
- package/dist/charts/registry.d.ts +36 -0
- package/dist/charts/registry.d.ts.map +1 -0
- package/dist/charts/registry.js +55 -0
- package/dist/charts/registry.js.map +1 -0
- package/dist/charts/sankey.d.ts +14 -0
- package/dist/charts/sankey.d.ts.map +1 -0
- package/dist/charts/sankey.js +74 -0
- package/dist/charts/sankey.js.map +1 -0
- package/dist/charts/scatter.d.ts +14 -0
- package/dist/charts/scatter.d.ts.map +1 -0
- package/dist/charts/scatter.js +130 -0
- package/dist/charts/scatter.js.map +1 -0
- package/dist/charts/sparkline.d.ts +19 -0
- package/dist/charts/sparkline.d.ts.map +1 -0
- package/dist/charts/sparkline.js +154 -0
- package/dist/charts/sparkline.js.map +1 -0
- package/dist/charts/waterfall.d.ts +14 -0
- package/dist/charts/waterfall.d.ts.map +1 -0
- package/dist/charts/waterfall.js +232 -0
- package/dist/charts/waterfall.js.map +1 -0
- package/dist/charts/xmr.d.ts +14 -0
- package/dist/charts/xmr.d.ts.map +1 -0
- package/dist/charts/xmr.js +456 -0
- package/dist/charts/xmr.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +120 -0
- package/dist/cli.js.map +1 -0
- package/dist/components/alert.d.ts +10 -0
- package/dist/components/alert.d.ts.map +1 -0
- package/dist/components/alert.js +65 -0
- package/dist/components/alert.js.map +1 -0
- package/dist/components/big_value.d.ts +10 -0
- package/dist/components/big_value.d.ts.map +1 -0
- package/dist/components/big_value.js +78 -0
- package/dist/components/big_value.js.map +1 -0
- package/dist/components/delta.d.ts +10 -0
- package/dist/components/delta.d.ts.map +1 -0
- package/dist/components/delta.js +83 -0
- package/dist/components/delta.js.map +1 -0
- package/dist/components/empty_space.d.ts +10 -0
- package/dist/components/empty_space.d.ts.map +1 -0
- package/dist/components/empty_space.js +29 -0
- package/dist/components/empty_space.js.map +1 -0
- package/dist/components/index.d.ts +21 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +23 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/note.d.ts +10 -0
- package/dist/components/note.d.ts.map +1 -0
- package/dist/components/note.js +66 -0
- package/dist/components/note.js.map +1 -0
- package/dist/components/registry.d.ts +24 -0
- package/dist/components/registry.d.ts.map +1 -0
- package/dist/components/registry.js +36 -0
- package/dist/components/registry.js.map +1 -0
- package/dist/components/table.d.ts +90 -0
- package/dist/components/table.d.ts.map +1 -0
- package/dist/components/table.js +610 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/text.d.ts +10 -0
- package/dist/components/text.d.ts.map +1 -0
- package/dist/components/text.js +46 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/textarea.d.ts +10 -0
- package/dist/components/textarea.d.ts.map +1 -0
- package/dist/components/textarea.js +79 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/core/colors.d.ts +45 -0
- package/dist/core/colors.d.ts.map +1 -0
- package/dist/core/colors.js +93 -0
- package/dist/core/colors.js.map +1 -0
- package/dist/core/css.d.ts +20 -0
- package/dist/core/css.d.ts.map +1 -0
- package/dist/core/css.js +97 -0
- package/dist/core/css.js.map +1 -0
- package/dist/core/exceptions.d.ts +59 -0
- package/dist/core/exceptions.d.ts.map +1 -0
- package/dist/core/exceptions.js +100 -0
- package/dist/core/exceptions.js.map +1 -0
- package/dist/core/formatting.d.ts +53 -0
- package/dist/core/formatting.d.ts.map +1 -0
- package/dist/core/formatting.js +491 -0
- package/dist/core/formatting.js.map +1 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/serializer.d.ts +29 -0
- package/dist/core/serializer.d.ts.map +1 -0
- package/dist/core/serializer.js +84 -0
- package/dist/core/serializer.js.map +1 -0
- package/dist/core/themes.d.ts +138 -0
- package/dist/core/themes.d.ts.map +1 -0
- package/dist/core/themes.js +484 -0
- package/dist/core/themes.js.map +1 -0
- package/dist/core/version-check.d.ts +23 -0
- package/dist/core/version-check.d.ts.map +1 -0
- package/dist/core/version-check.js +163 -0
- package/dist/core/version-check.js.map +1 -0
- package/dist/generate_test_harness.d.ts +13 -0
- package/dist/generate_test_harness.d.ts.map +1 -0
- package/dist/generate_test_harness.js +35 -0
- package/dist/generate_test_harness.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/converter.d.ts +22 -0
- package/dist/layout/converter.d.ts.map +1 -0
- package/dist/layout/converter.js +46 -0
- package/dist/layout/converter.js.map +1 -0
- package/dist/layout/csv.d.ts +15 -0
- package/dist/layout/csv.d.ts.map +1 -0
- package/dist/layout/csv.js +88 -0
- package/dist/layout/csv.js.map +1 -0
- package/dist/layout/dispatcher.d.ts +13 -0
- package/dist/layout/dispatcher.d.ts.map +1 -0
- package/dist/layout/dispatcher.js +47 -0
- package/dist/layout/dispatcher.js.map +1 -0
- package/dist/layout/index.d.ts +8 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +8 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/parser.d.ts +19 -0
- package/dist/layout/parser.d.ts.map +1 -0
- package/dist/layout/parser.js +888 -0
- package/dist/layout/parser.js.map +1 -0
- package/dist/layout/templates.d.ts +32 -0
- package/dist/layout/templates.d.ts.map +1 -0
- package/dist/layout/templates.js +1016 -0
- package/dist/layout/templates.js.map +1 -0
- package/dist/types.d.ts +144 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +14 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alert/banner component
|
|
3
|
+
*/
|
|
4
|
+
import { COLORS, FONT_STACK, FONT_SIZE_MD, FONT_SIZE_LG, FONT_SIZE_SM, SPACING_XL, SPACING_LG, SPACING_MD, ALERT_ICONS, getThemeColors, } from '../core/themes.js';
|
|
5
|
+
import { registerComponent } from './registry.js';
|
|
6
|
+
/**
|
|
7
|
+
* Generate an alert/banner component
|
|
8
|
+
*/
|
|
9
|
+
function generateAlert(spec) {
|
|
10
|
+
const message = spec.message ?? '';
|
|
11
|
+
const alertType = (spec.alertType ?? 'info');
|
|
12
|
+
const title = spec.title ?? '';
|
|
13
|
+
const theme = (spec.theme ?? 'light');
|
|
14
|
+
const colors = getThemeColors(theme);
|
|
15
|
+
// Alert type colors
|
|
16
|
+
const alertColors = {
|
|
17
|
+
info: COLORS.INFO_BLUE,
|
|
18
|
+
success: COLORS.POSITIVE_GREEN,
|
|
19
|
+
warning: COLORS.WARNING_AMBER,
|
|
20
|
+
error: COLORS.ERROR_RED,
|
|
21
|
+
};
|
|
22
|
+
const alertColor = alertColors[alertType] ?? COLORS.INFO_BLUE;
|
|
23
|
+
const icon = ALERT_ICONS[alertType] ?? ALERT_ICONS.info;
|
|
24
|
+
const titleUpper = title.toUpperCase();
|
|
25
|
+
const titleHtml = title ? `<h2>${titleUpper}</h2>` : '';
|
|
26
|
+
return `<!DOCTYPE html>
|
|
27
|
+
<html lang="en">
|
|
28
|
+
<head>
|
|
29
|
+
<meta charset="utf-8">
|
|
30
|
+
<title>${title}</title>
|
|
31
|
+
<style>
|
|
32
|
+
* { box-sizing: border-box; }
|
|
33
|
+
html, body {
|
|
34
|
+
margin: 0; padding: 0; width: 100%; height: 100%;
|
|
35
|
+
background-color: ${colors.background}; font-family: ${FONT_STACK};
|
|
36
|
+
}
|
|
37
|
+
.container { padding: ${SPACING_XL}px; width: 100%; }
|
|
38
|
+
h2 {
|
|
39
|
+
font-family: ${FONT_STACK}; font-weight: 700; color: ${colors.text};
|
|
40
|
+
font-size: ${FONT_SIZE_MD}px; margin: 0 0 ${SPACING_LG}px 0; letter-spacing: 0.05em;
|
|
41
|
+
}
|
|
42
|
+
.alert {
|
|
43
|
+
display: flex; align-items: flex-start; gap: ${SPACING_MD}px; padding: ${SPACING_LG}px;
|
|
44
|
+
border-left: 3px solid ${alertColor};
|
|
45
|
+
background-color: ${alertColor}1a;
|
|
46
|
+
}
|
|
47
|
+
.icon { font-size: ${FONT_SIZE_LG}px; color: ${alertColor}; flex-shrink: 0; margin-top: 1px; }
|
|
48
|
+
.message { font-size: ${FONT_SIZE_SM}px; color: ${colors.text}; line-height: 1.5; }
|
|
49
|
+
</style>
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<div class="container">
|
|
53
|
+
${titleHtml}
|
|
54
|
+
<div class="alert">
|
|
55
|
+
<span class="icon">${icon}</span>
|
|
56
|
+
<span class="message">${message}</span>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</body>
|
|
60
|
+
</html>`;
|
|
61
|
+
}
|
|
62
|
+
// Register the component
|
|
63
|
+
registerComponent('alert')(generateAlert);
|
|
64
|
+
export { generateAlert };
|
|
65
|
+
//# sourceMappingURL=alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert.js","sourceRoot":"","sources":["../../components/alert.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,MAAM,EACN,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIlD;;GAEG;AACH,SAAS,aAAa,CAAC,IAAmB;IACxC,MAAM,OAAO,GAAI,IAAI,CAAC,OAAkB,IAAI,EAAE,CAAC;IAC/C,MAAM,SAAS,GAAG,CAAE,IAAI,CAAC,SAAoB,IAAI,MAAM,CAAc,CAAC;IACtE,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAI,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAU,CAAC;IAE/C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAErC,oBAAoB;IACpB,MAAM,WAAW,GAA8B;QAC7C,IAAI,EAAE,MAAM,CAAC,SAAS;QACtB,OAAO,EAAE,MAAM,CAAC,cAAc;QAC9B,OAAO,EAAE,MAAM,CAAC,aAAa;QAC7B,KAAK,EAAE,MAAM,CAAC,SAAS;KACxB,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC;IAC9D,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC;IAExD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAExD,OAAO;;;;WAIE,KAAK;;;;;0BAKU,MAAM,CAAC,UAAU,kBAAkB,UAAU;;4BAE3C,UAAU;;qBAEjB,UAAU,8BAA8B,MAAM,CAAC,IAAI;mBACrD,YAAY,mBAAmB,UAAU;;;qDAGP,UAAU,gBAAgB,UAAU;+BAC1D,UAAU;0BACf,UAAU;;yBAEX,YAAY,cAAc,UAAU;4BACjC,YAAY,cAAc,MAAM,CAAC,IAAI;;;;;MAK3D,SAAS;;2BAEY,IAAI;8BACD,OAAO;;;;QAI7B,CAAC;AACT,CAAC;AAED,yBAAyB;AACzB,iBAAiB,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Big value display component
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentSpec } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a big value display for key metrics
|
|
7
|
+
*/
|
|
8
|
+
declare function generateBigValue(spec: ComponentSpec): string;
|
|
9
|
+
export { generateBigValue };
|
|
10
|
+
//# sourceMappingURL=big_value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"big_value.d.ts","sourceRoot":"","sources":["../../components/big_value.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,aAAa,CAAC;AAKpE;;GAEG;AACH,iBAAS,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAwErD;AAKD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Big value display component
|
|
3
|
+
*/
|
|
4
|
+
import { COLORS, FONT_STACK, getThemeColors } from '../core/themes.js';
|
|
5
|
+
import { formatNumber, inferFormat } from '../core/formatting.js';
|
|
6
|
+
import { registerComponent } from './registry.js';
|
|
7
|
+
/**
|
|
8
|
+
* Generate a big value display for key metrics
|
|
9
|
+
*/
|
|
10
|
+
function generateBigValue(spec) {
|
|
11
|
+
const value = typeof spec.value === 'number' ? spec.value : 0;
|
|
12
|
+
const specLabel = spec.label;
|
|
13
|
+
const specTitle = spec.title;
|
|
14
|
+
const theme = (spec.theme ?? 'light');
|
|
15
|
+
const comparison = spec.comparison;
|
|
16
|
+
// If only title is provided (no label), use title as the label below the number
|
|
17
|
+
// This matches user expectations that "title" describes what the number represents
|
|
18
|
+
const label = specLabel ?? specTitle ?? '';
|
|
19
|
+
// Only show H2 header if BOTH title and label are explicitly provided
|
|
20
|
+
const showTitleHeader = specTitle && specLabel;
|
|
21
|
+
const title = showTitleHeader ? specTitle : '';
|
|
22
|
+
// Auto-infer format from label if not specified
|
|
23
|
+
const fmt = spec.format ?? inferFormat(label, value);
|
|
24
|
+
const colors = getThemeColors(theme);
|
|
25
|
+
const displayValue = formatNumber(value, fmt);
|
|
26
|
+
let comparisonHtml = '';
|
|
27
|
+
if (comparison) {
|
|
28
|
+
const compVal = comparison.value ?? 0;
|
|
29
|
+
const compLabel = comparison.label ?? '';
|
|
30
|
+
const isPositive = compVal >= 0;
|
|
31
|
+
const arrow = isPositive ? '↑' : '↓';
|
|
32
|
+
const compColor = isPositive ? COLORS.POSITIVE_GREEN : COLORS.ERROR_RED;
|
|
33
|
+
const compDisplay = formatNumber(compVal, comparison.format, true);
|
|
34
|
+
comparisonHtml = `
|
|
35
|
+
<div style="display: flex; align-items: center; gap: 4px; margin-top: 8px;">
|
|
36
|
+
<span style="color: ${compColor}; font-size: 14px;">${arrow} ${compDisplay}</span>
|
|
37
|
+
<span style="color: ${colors.textSecondary}; font-size: 12px;">${compLabel}</span>
|
|
38
|
+
</div>`;
|
|
39
|
+
}
|
|
40
|
+
const titleUpper = title.toUpperCase();
|
|
41
|
+
const titleHtml = title ? `<h2>${titleUpper}</h2>` : '';
|
|
42
|
+
return `<!DOCTYPE html>
|
|
43
|
+
<html lang="en">
|
|
44
|
+
<head>
|
|
45
|
+
<meta charset="utf-8">
|
|
46
|
+
<title>${title}</title>
|
|
47
|
+
<style>
|
|
48
|
+
* { box-sizing: border-box; }
|
|
49
|
+
html, body {
|
|
50
|
+
margin: 0; padding: 0; width: 100%; height: 100%;
|
|
51
|
+
background-color: ${colors.background}; font-family: ${FONT_STACK};
|
|
52
|
+
}
|
|
53
|
+
.container { padding: 24px; width: 100%; }
|
|
54
|
+
h2 {
|
|
55
|
+
font-family: ${FONT_STACK}; font-weight: 700; color: ${colors.text};
|
|
56
|
+
font-size: 16px; margin: 0 0 16px 0; letter-spacing: 0.05em;
|
|
57
|
+
}
|
|
58
|
+
.big-value {
|
|
59
|
+
font-family: ${FONT_STACK}; font-weight: 700;
|
|
60
|
+
font-size: 48px; color: ${colors.text}; line-height: 1;
|
|
61
|
+
}
|
|
62
|
+
.label { font-size: 14px; color: ${colors.textSecondary}; margin-top: 8px; }
|
|
63
|
+
</style>
|
|
64
|
+
</head>
|
|
65
|
+
<body>
|
|
66
|
+
<div class="container">
|
|
67
|
+
${titleHtml}
|
|
68
|
+
<div class="big-value">${displayValue}</div>
|
|
69
|
+
<div class="label">${label}</div>
|
|
70
|
+
${comparisonHtml}
|
|
71
|
+
</div>
|
|
72
|
+
</body>
|
|
73
|
+
</html>`;
|
|
74
|
+
}
|
|
75
|
+
// Register the component
|
|
76
|
+
registerComponent('big_value')(generateBigValue);
|
|
77
|
+
export { generateBigValue };
|
|
78
|
+
//# sourceMappingURL=big_value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"big_value.js","sourceRoot":"","sources":["../../components/big_value.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAmB;IAC3C,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,KAA2B,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAA2B,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAU,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,UAEX,CAAC;IAEd,gFAAgF;IAChF,mFAAmF;IACnF,MAAM,KAAK,GAAG,SAAS,IAAI,SAAS,IAAI,EAAE,CAAC;IAC3C,sEAAsE;IACtE,MAAM,eAAe,GAAG,SAAS,IAAI,SAAS,CAAC;IAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/C,gDAAgD;IAChD,MAAM,GAAG,GAAI,IAAI,CAAC,MAAiC,IAAI,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEjF,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAE9C,IAAI,cAAc,GAAG,EAAE,CAAC;IACxB,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACrC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;QACxE,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnE,cAAc,GAAG;;8BAES,SAAS,uBAAuB,KAAK,IAAI,WAAW;8BACpD,MAAM,CAAC,aAAa,uBAAuB,SAAS;aACrE,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAExD,OAAO;;;;WAIE,KAAK;;;;;0BAKU,MAAM,CAAC,UAAU,kBAAkB,UAAU;;;;qBAIlD,UAAU,8BAA8B,MAAM,CAAC,IAAI;;;;qBAInD,UAAU;gCACC,MAAM,CAAC,IAAI;;uCAEJ,MAAM,CAAC,aAAa;;;;;MAKrD,SAAS;6BACc,YAAY;yBAChB,KAAK;MACxB,cAAc;;;QAGZ,CAAC;AACT,CAAC;AAED,yBAAyB;AACzB,iBAAiB,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delta/change indicator component
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentSpec } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a delta/change indicator
|
|
7
|
+
*/
|
|
8
|
+
declare function generateDelta(spec: ComponentSpec): string;
|
|
9
|
+
export { generateDelta };
|
|
10
|
+
//# sourceMappingURL=delta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delta.d.ts","sourceRoot":"","sources":["../../components/delta.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,aAAa,CAAC;AAKpE;;GAEG;AACH,iBAAS,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA4ElD;AAKD,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delta/change indicator component
|
|
3
|
+
*/
|
|
4
|
+
import { COLORS, FONT_STACK, getThemeColors } from '../core/themes.js';
|
|
5
|
+
import { formatNumber, inferFormat } from '../core/formatting.js';
|
|
6
|
+
import { registerComponent } from './registry.js';
|
|
7
|
+
/**
|
|
8
|
+
* Generate a delta/change indicator
|
|
9
|
+
*/
|
|
10
|
+
function generateDelta(spec) {
|
|
11
|
+
const value = typeof spec.value === 'number' ? spec.value : 0;
|
|
12
|
+
const specLabel = spec.label;
|
|
13
|
+
const specTitle = spec.title;
|
|
14
|
+
const theme = (spec.theme ?? 'light');
|
|
15
|
+
const neutralIs = spec.neutralIs ?? 0;
|
|
16
|
+
const positiveIsGood = spec.positiveIsGood !== false; // Default true
|
|
17
|
+
// If only title is provided (no label), use title as the label below
|
|
18
|
+
// If both provided, title becomes H2 header and label goes below
|
|
19
|
+
const label = specLabel ?? specTitle ?? '';
|
|
20
|
+
const showTitleHeader = specTitle && specLabel;
|
|
21
|
+
const title = showTitleHeader ? specTitle : '';
|
|
22
|
+
// Auto-infer format from label if not specified
|
|
23
|
+
const fmt = spec.format ?? inferFormat(label, value);
|
|
24
|
+
const colors = getThemeColors(theme);
|
|
25
|
+
// Determine direction and color
|
|
26
|
+
const isPositive = value > neutralIs;
|
|
27
|
+
const isNegative = value < neutralIs;
|
|
28
|
+
const isNeutral = value === neutralIs;
|
|
29
|
+
let color;
|
|
30
|
+
let arrow;
|
|
31
|
+
if (isNeutral) {
|
|
32
|
+
color = colors.textSecondary;
|
|
33
|
+
arrow = '→';
|
|
34
|
+
}
|
|
35
|
+
else if ((isPositive && positiveIsGood) || (isNegative && !positiveIsGood)) {
|
|
36
|
+
color = COLORS.POSITIVE_GREEN;
|
|
37
|
+
arrow = isPositive ? '↑' : '↓';
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
color = COLORS.ERROR_RED;
|
|
41
|
+
arrow = isPositive ? '↑' : '↓';
|
|
42
|
+
}
|
|
43
|
+
const displayValue = formatNumber(value, fmt, true);
|
|
44
|
+
const titleUpper = title.toUpperCase();
|
|
45
|
+
const titleHtml = title ? `<h2>${titleUpper}</h2>` : '';
|
|
46
|
+
return `<!DOCTYPE html>
|
|
47
|
+
<html lang="en">
|
|
48
|
+
<head>
|
|
49
|
+
<meta charset="utf-8">
|
|
50
|
+
<title>${title}</title>
|
|
51
|
+
<style>
|
|
52
|
+
* { box-sizing: border-box; }
|
|
53
|
+
html, body {
|
|
54
|
+
margin: 0; padding: 0; width: 100%; height: 100%;
|
|
55
|
+
background-color: ${colors.background}; font-family: ${FONT_STACK};
|
|
56
|
+
}
|
|
57
|
+
.container { padding: 24px; width: 100%; }
|
|
58
|
+
h2 {
|
|
59
|
+
font-family: ${FONT_STACK}; font-weight: 700; color: ${colors.text};
|
|
60
|
+
font-size: 16px; margin: 0 0 16px 0; letter-spacing: 0.05em;
|
|
61
|
+
}
|
|
62
|
+
.delta { display: flex; align-items: center; gap: 8px; }
|
|
63
|
+
.arrow { font-size: 24px; }
|
|
64
|
+
.value { font-family: ${FONT_STACK}; font-size: 24px; font-weight: bold; }
|
|
65
|
+
.label { font-size: 14px; color: ${colors.textSecondary}; margin-top: 8px; }
|
|
66
|
+
</style>
|
|
67
|
+
</head>
|
|
68
|
+
<body>
|
|
69
|
+
<div class="container">
|
|
70
|
+
${titleHtml}
|
|
71
|
+
<div class="delta">
|
|
72
|
+
<span class="arrow" style="color: ${color};">${arrow}</span>
|
|
73
|
+
<span class="value" style="color: ${color};">${displayValue}</span>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="label">${label}</div>
|
|
76
|
+
</div>
|
|
77
|
+
</body>
|
|
78
|
+
</html>`;
|
|
79
|
+
}
|
|
80
|
+
// Register the component
|
|
81
|
+
registerComponent('delta')(generateDelta);
|
|
82
|
+
export { generateDelta };
|
|
83
|
+
//# sourceMappingURL=delta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../components/delta.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,SAAS,aAAa,CAAC,IAAmB;IACxC,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,KAA2B,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAA2B,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAU,CAAC;IAC/C,MAAM,SAAS,GAAI,IAAI,CAAC,SAAoB,IAAI,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC,CAAC,eAAe;IAErE,qEAAqE;IACrE,iEAAiE;IACjE,MAAM,KAAK,GAAG,SAAS,IAAI,SAAS,IAAI,EAAE,CAAC;IAC3C,MAAM,eAAe,GAAG,SAAS,IAAI,SAAS,CAAC;IAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/C,gDAAgD;IAChD,MAAM,GAAG,GAAI,IAAI,CAAC,MAAiC,IAAI,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEjF,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAErC,gCAAgC;IAChC,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IACrC,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC;IAEtC,IAAI,KAAa,CAAC;IAClB,IAAI,KAAa,CAAC;IAElB,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;QAC7B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,CAAC,UAAU,IAAI,cAAc,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAC7E,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;QAC9B,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;QACzB,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACjC,CAAC;IAED,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAExD,OAAO;;;;WAIE,KAAK;;;;;0BAKU,MAAM,CAAC,UAAU,kBAAkB,UAAU;;;;qBAIlD,UAAU,8BAA8B,MAAM,CAAC,IAAI;;;;;4BAK5C,UAAU;uCACC,MAAM,CAAC,aAAa;;;;;MAKrD,SAAS;;0CAE2B,KAAK,MAAM,KAAK;0CAChB,KAAK,MAAM,YAAY;;yBAExC,KAAK;;;QAGtB,CAAC;AACT,CAAC;AAED,yBAAyB;AACzB,iBAAiB,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Empty space component for layout purposes
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentSpec } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate an empty space component for layout purposes
|
|
7
|
+
*/
|
|
8
|
+
declare function generateEmptySpace(spec: ComponentSpec): string;
|
|
9
|
+
export { generateEmptySpace };
|
|
10
|
+
//# sourceMappingURL=empty_space.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty_space.d.ts","sourceRoot":"","sources":["../../components/empty_space.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAS,MAAM,aAAa,CAAC;AAIxD;;GAEG;AACH,iBAAS,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAiBvD;AAKD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Empty space component for layout purposes
|
|
3
|
+
*/
|
|
4
|
+
import { getThemeColors } from '../core/themes.js';
|
|
5
|
+
import { registerComponent } from './registry.js';
|
|
6
|
+
/**
|
|
7
|
+
* Generate an empty space component for layout purposes
|
|
8
|
+
*/
|
|
9
|
+
function generateEmptySpace(spec) {
|
|
10
|
+
const theme = (spec.theme ?? 'light');
|
|
11
|
+
const colors = getThemeColors(theme);
|
|
12
|
+
return `<!DOCTYPE html>
|
|
13
|
+
<html lang="en">
|
|
14
|
+
<head>
|
|
15
|
+
<meta charset="utf-8">
|
|
16
|
+
<style>
|
|
17
|
+
html, body {
|
|
18
|
+
margin: 0; padding: 0; width: 100%; height: 100%;
|
|
19
|
+
background-color: ${colors.background};
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body></body>
|
|
24
|
+
</html>`;
|
|
25
|
+
}
|
|
26
|
+
// Register the component
|
|
27
|
+
registerComponent('empty_space')(generateEmptySpace);
|
|
28
|
+
export { generateEmptySpace };
|
|
29
|
+
//# sourceMappingURL=empty_space.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty_space.js","sourceRoot":"","sources":["../../components/empty_space.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,SAAS,kBAAkB,CAAC,IAAmB;IAC7C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAU,CAAC;IAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAErC,OAAO;;;;;;;0BAOiB,MAAM,CAAC,UAAU;;;;;QAKnC,CAAC;AACT,CAAC;AAED,yBAAyB;AACzB,iBAAiB,CAAC,aAAa,CAAC,CAAC,kBAAkB,CAAC,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Components module exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './registry.js';
|
|
5
|
+
import './big_value.js';
|
|
6
|
+
import './delta.js';
|
|
7
|
+
import './alert.js';
|
|
8
|
+
import './note.js';
|
|
9
|
+
import './text.js';
|
|
10
|
+
import './textarea.js';
|
|
11
|
+
import './empty_space.js';
|
|
12
|
+
import './table.js';
|
|
13
|
+
export { generateBigValue } from './big_value.js';
|
|
14
|
+
export { generateDelta } from './delta.js';
|
|
15
|
+
export { generateAlert } from './alert.js';
|
|
16
|
+
export { generateNote } from './note.js';
|
|
17
|
+
export { generateText } from './text.js';
|
|
18
|
+
export { generateTextarea } from './textarea.js';
|
|
19
|
+
export { generateEmptySpace } from './empty_space.js';
|
|
20
|
+
export { generateTable, formatCell, computeHeatmapRanges, computeDumbbellRanges, renderSparklineSvg, renderPctBarSvg, renderDumbbellSvg, } from './table.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC;AAG9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,YAAY,CAAC;AACpB,OAAO,YAAY,CAAC;AACpB,OAAO,WAAW,CAAC;AACnB,OAAO,WAAW,CAAC;AACnB,OAAO,eAAe,CAAC;AACvB,OAAO,kBAAkB,CAAC;AAC1B,OAAO,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Components module exports
|
|
3
|
+
*/
|
|
4
|
+
export * from './registry.js';
|
|
5
|
+
// Import component modules to trigger registration
|
|
6
|
+
import './big_value.js';
|
|
7
|
+
import './delta.js';
|
|
8
|
+
import './alert.js';
|
|
9
|
+
import './note.js';
|
|
10
|
+
import './text.js';
|
|
11
|
+
import './textarea.js';
|
|
12
|
+
import './empty_space.js';
|
|
13
|
+
import './table.js';
|
|
14
|
+
// Re-export component generators for direct use
|
|
15
|
+
export { generateBigValue } from './big_value.js';
|
|
16
|
+
export { generateDelta } from './delta.js';
|
|
17
|
+
export { generateAlert } from './alert.js';
|
|
18
|
+
export { generateNote } from './note.js';
|
|
19
|
+
export { generateText } from './text.js';
|
|
20
|
+
export { generateTextarea } from './textarea.js';
|
|
21
|
+
export { generateEmptySpace } from './empty_space.js';
|
|
22
|
+
export { generateTable, formatCell, computeHeatmapRanges, computeDumbbellRanges, renderSparklineSvg, renderPctBarSvg, renderDumbbellSvg, } from './table.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC;AAE9B,mDAAmD;AACnD,OAAO,gBAAgB,CAAC;AACxB,OAAO,YAAY,CAAC;AACpB,OAAO,YAAY,CAAC;AACpB,OAAO,WAAW,CAAC;AACnB,OAAO,WAAW,CAAC;AACnB,OAAO,eAAe,CAAC;AACvB,OAAO,kBAAkB,CAAC;AAC1B,OAAO,YAAY,CAAC;AAEpB,gDAAgD;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Note/callout component
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentSpec } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a note with left border and tinted background
|
|
7
|
+
*/
|
|
8
|
+
declare function generateNote(spec: ComponentSpec): string;
|
|
9
|
+
export { generateNote };
|
|
10
|
+
//# sourceMappingURL=note.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../components/note.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAS,MAAM,aAAa,CAAC;AAMxD;;GAEG;AACH,iBAAS,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA0DjD;AAKD,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Note/callout component
|
|
3
|
+
*/
|
|
4
|
+
import { FONT_STACK, NOTE_COLORS, getThemeColors } from '../core/themes.js';
|
|
5
|
+
import { registerComponent } from './registry.js';
|
|
6
|
+
/**
|
|
7
|
+
* Generate a note with left border and tinted background
|
|
8
|
+
*/
|
|
9
|
+
function generateNote(spec) {
|
|
10
|
+
const content = spec.content ?? '';
|
|
11
|
+
const label = spec.label ?? ''; // Optional bold label
|
|
12
|
+
const title = spec.title ?? '';
|
|
13
|
+
const theme = (spec.theme ?? 'light');
|
|
14
|
+
const noteType = (spec.noteType ?? 'default');
|
|
15
|
+
const borderColor = NOTE_COLORS[noteType] ?? NOTE_COLORS.default;
|
|
16
|
+
const colors = getThemeColors(theme);
|
|
17
|
+
// Light tinted background
|
|
18
|
+
const bgTint = theme === 'light' ? `${colors.border}40` : `${colors.border}30`;
|
|
19
|
+
const titleUpper = title.toUpperCase();
|
|
20
|
+
const titleHtml = title ? `<h2>${titleUpper}</h2>` : '';
|
|
21
|
+
// Build content with optional bold label
|
|
22
|
+
const contentHtml = label ? `<strong>${label}</strong> ${content}` : content;
|
|
23
|
+
return `<!DOCTYPE html>
|
|
24
|
+
<html lang="en">
|
|
25
|
+
<head>
|
|
26
|
+
<meta charset="utf-8">
|
|
27
|
+
<title>${title}</title>
|
|
28
|
+
<style>
|
|
29
|
+
* { box-sizing: border-box; }
|
|
30
|
+
html, body {
|
|
31
|
+
margin: 0; padding: 0; width: 100%; height: 100%;
|
|
32
|
+
background-color: ${colors.background}; font-family: ${FONT_STACK};
|
|
33
|
+
}
|
|
34
|
+
.container {
|
|
35
|
+
padding: 12px 16px; width: 100%;
|
|
36
|
+
display: flex; flex-direction: column; justify-content: center; height: 100%;
|
|
37
|
+
}
|
|
38
|
+
h2 {
|
|
39
|
+
font-family: ${FONT_STACK}; font-weight: 700; color: ${colors.text};
|
|
40
|
+
font-size: 14px; margin: 0 0 8px 0; letter-spacing: 0.05em;
|
|
41
|
+
}
|
|
42
|
+
.note {
|
|
43
|
+
border-left: 3px solid ${borderColor};
|
|
44
|
+
background-color: ${bgTint};
|
|
45
|
+
padding: 12px 16px;
|
|
46
|
+
}
|
|
47
|
+
.note-content {
|
|
48
|
+
font-size: 13px; color: ${colors.text}; line-height: 1.5;
|
|
49
|
+
}
|
|
50
|
+
.note-content strong { font-weight: 700; }
|
|
51
|
+
</style>
|
|
52
|
+
</head>
|
|
53
|
+
<body>
|
|
54
|
+
<div class="container">
|
|
55
|
+
${titleHtml}
|
|
56
|
+
<div class="note">
|
|
57
|
+
<div class="note-content">${contentHtml}</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</body>
|
|
61
|
+
</html>`;
|
|
62
|
+
}
|
|
63
|
+
// Register the component
|
|
64
|
+
registerComponent('note')(generateNote);
|
|
65
|
+
export { generateNote };
|
|
66
|
+
//# sourceMappingURL=note.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"note.js","sourceRoot":"","sources":["../../components/note.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIlD;;GAEG;AACH,SAAS,YAAY,CAAC,IAAmB;IACvC,MAAM,OAAO,GAAI,IAAI,CAAC,OAAkB,IAAI,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAI,EAAE,CAAC,CAAC,sBAAsB;IAClE,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAI,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAU,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAE,IAAI,CAAC,QAAmB,IAAI,SAAS,CAAa,CAAC;IAEtE,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC;IACjE,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAErC,0BAA0B;IAC1B,MAAM,MAAM,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC;IAE/E,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAExD,yCAAyC;IACzC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,KAAK,aAAa,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAE7E,OAAO;;;;WAIE,KAAK;;;;;0BAKU,MAAM,CAAC,UAAU,kBAAkB,UAAU;;;;;;;qBAOlD,UAAU,8BAA8B,MAAM,CAAC,IAAI;;;;+BAIzC,WAAW;0BAChB,MAAM;;;;gCAIA,MAAM,CAAC,IAAI;;;;;;;MAOrC,SAAS;;kCAEmB,WAAW;;;;QAIrC,CAAC;AACT,CAAC;AAED,yBAAyB;AACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component registry for mviz
|
|
3
|
+
*
|
|
4
|
+
* Components register themselves using the @registerComponent decorator.
|
|
5
|
+
* The dispatcher uses this registry to route specs to generators.
|
|
6
|
+
*/
|
|
7
|
+
import type { ComponentGenerator } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Registry of component generators by type
|
|
10
|
+
*/
|
|
11
|
+
export declare const COMPONENT_REGISTRY: Map<string, ComponentGenerator>;
|
|
12
|
+
/**
|
|
13
|
+
* Decorator to register a component generator
|
|
14
|
+
*/
|
|
15
|
+
export declare function registerComponent(type: string): (generator: ComponentGenerator) => ComponentGenerator;
|
|
16
|
+
/**
|
|
17
|
+
* Get all registered component types
|
|
18
|
+
*/
|
|
19
|
+
export declare function getRegisteredComponentTypes(): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Check if a type is a registered component
|
|
22
|
+
*/
|
|
23
|
+
export declare function isComponentType(type: string): boolean;
|
|
24
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../components/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,kBAAkB,iCAAwC,CAAC;AAExE;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,SAAS,EAAE,kBAAkB,KAAK,kBAAkB,CAKrG;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,EAAE,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component registry for mviz
|
|
3
|
+
*
|
|
4
|
+
* Components register themselves using the @registerComponent decorator.
|
|
5
|
+
* The dispatcher uses this registry to route specs to generators.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Registry of component generators by type
|
|
9
|
+
*/
|
|
10
|
+
export const COMPONENT_REGISTRY = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Decorator to register a component generator
|
|
13
|
+
*/
|
|
14
|
+
export function registerComponent(type) {
|
|
15
|
+
return (generator) => {
|
|
16
|
+
COMPONENT_REGISTRY.set(type, generator);
|
|
17
|
+
return generator;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get all registered component types
|
|
22
|
+
*/
|
|
23
|
+
export function getRegisteredComponentTypes() {
|
|
24
|
+
return Array.from(COMPONENT_REGISTRY.keys());
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if a type is a registered component
|
|
28
|
+
*/
|
|
29
|
+
export function isComponentType(type) {
|
|
30
|
+
return COMPONENT_REGISTRY.has(type);
|
|
31
|
+
}
|
|
32
|
+
// TODO: Import component modules here to trigger registration
|
|
33
|
+
// import './big_value.js';
|
|
34
|
+
// import './delta.js';
|
|
35
|
+
// etc.
|
|
36
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../components/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA8B,CAAC;AAExE;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,CAAC,SAA6B,EAAsB,EAAE;QAC3D,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,8DAA8D;AAC9D,2BAA2B;AAC3B,uBAAuB;AACvB,OAAO"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data table component
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentSpec } from '../types.js';
|
|
5
|
+
import { getThemeColors } from '../core/themes.js';
|
|
6
|
+
import { type FormatType } from '../core/formatting.js';
|
|
7
|
+
/**
|
|
8
|
+
* Column definition for table configuration
|
|
9
|
+
*/
|
|
10
|
+
export interface ColumnDef {
|
|
11
|
+
id: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
align?: 'left' | 'center' | 'right';
|
|
14
|
+
fmt?: FormatType;
|
|
15
|
+
bold?: boolean;
|
|
16
|
+
italic?: boolean;
|
|
17
|
+
type?: 'sparkline' | 'heatmap';
|
|
18
|
+
sparkType?: 'line' | 'bar' | 'area' | 'pct_bar' | 'pct' | 'dumbbell';
|
|
19
|
+
color?: string;
|
|
20
|
+
width?: number;
|
|
21
|
+
height?: number;
|
|
22
|
+
markers?: boolean;
|
|
23
|
+
showLabel?: boolean;
|
|
24
|
+
higherIsBetter?: boolean;
|
|
25
|
+
heatmapColors?: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of formatting a cell
|
|
29
|
+
*/
|
|
30
|
+
export interface CellResult {
|
|
31
|
+
content: string;
|
|
32
|
+
bgColor: string | null;
|
|
33
|
+
textColor: string | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Style overrides for a cell
|
|
37
|
+
*/
|
|
38
|
+
export interface CellStyles {
|
|
39
|
+
bold: boolean;
|
|
40
|
+
italic: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract raw value and style overrides from cell data
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractCellValue(value: unknown, colDef: ColumnDef): {
|
|
46
|
+
value: unknown;
|
|
47
|
+
styles: CellStyles;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Render an inline SVG percentage bar with optional label
|
|
51
|
+
*/
|
|
52
|
+
export declare function renderPctBarSvg(value: number, width?: number, height?: number, color?: string, bgColor?: string, showLabel?: boolean, textColor?: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Render an inline dumbbell sparkline with shared column scale
|
|
55
|
+
*/
|
|
56
|
+
export declare function renderDumbbellSvg(start: number, end: number, colMin: number, colMax: number, width?: number, height?: number, higherIsBetter?: boolean): string;
|
|
57
|
+
/**
|
|
58
|
+
* Render an inline SVG sparkline with interactive tooltips
|
|
59
|
+
*/
|
|
60
|
+
export declare function renderSparklineSvg(values: unknown[], sparkType?: string, width?: number, height?: number, color?: string, markers?: boolean): string;
|
|
61
|
+
/**
|
|
62
|
+
* Compute min/max ranges for heatmap columns
|
|
63
|
+
*/
|
|
64
|
+
export declare function computeHeatmapRanges(columns: ColumnDef[], data: Record<string, unknown>[]): Map<string, {
|
|
65
|
+
min: number;
|
|
66
|
+
max: number;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Compute min/max ranges for dumbbell sparkline columns
|
|
70
|
+
*/
|
|
71
|
+
export declare function computeDumbbellRanges(columns: ColumnDef[], data: Record<string, unknown>[]): Map<string, {
|
|
72
|
+
min: number;
|
|
73
|
+
max: number;
|
|
74
|
+
}>;
|
|
75
|
+
/**
|
|
76
|
+
* Format a cell value and return content with optional styling
|
|
77
|
+
*/
|
|
78
|
+
export declare function formatCell(value: unknown, colDef: ColumnDef, themeColors: ReturnType<typeof getThemeColors>, heatmapRanges: Map<string, {
|
|
79
|
+
min: number;
|
|
80
|
+
max: number;
|
|
81
|
+
}>, dumbbellRanges: Map<string, {
|
|
82
|
+
min: number;
|
|
83
|
+
max: number;
|
|
84
|
+
}>, defaultHeatmapColors: string[]): CellResult;
|
|
85
|
+
/**
|
|
86
|
+
* Generate a styled data table
|
|
87
|
+
*/
|
|
88
|
+
declare function generateTable(spec: ComponentSpec): string;
|
|
89
|
+
export { generateTable };
|
|
90
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../components/table.ts"],"names":[],"mappings":"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"}
|