api-server / templates /widget-render.html
XWX-AI's picture
feat: add widget renderer (chart.js, mermaid) and bump to v2.0.0
44a8902
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { margin: 0; padding: 8px; background: #ffffff; font-family: system-ui, -apple-system, sans-serif; }
/* Claude Semantic Color Classes */
.c-purple { fill: #EEEDFE; stroke: #534AB7; color: #3C3489; }
.c-teal { fill: #E1F5EE; stroke: #0F6E56; color: #085041; }
.c-coral { fill: #FAECE7; stroke: #993C1D; color: #712B13; }
.c-pink { fill: #FBEAF0; stroke: #993556; color: #72243E; }
.c-gray { fill: #F1EFE8; stroke: #5F5E5A; color: #444441; }
.c-blue { fill: #E6F1FB; stroke: #185FA5; color: #0C447C; }
.c-green { fill: #EAF3DE; stroke: #3B6D11; color: #27500A; }
.c-amber { fill: #FAEEDA; stroke: #854F0B; color: #633806; }
.c-red { fill: #FCEBEB; stroke: #A32D2D; color: #791F1F; }
.c-purple rect, .c-purple circle, .c-purple ellipse, .c-purple polygon { fill: #EEEDFE; stroke: #534AB7; }
.c-teal rect, .c-teal circle, .c-teal ellipse, .c-teal polygon { fill: #E1F5EE; stroke: #0F6E56; }
.c-coral rect, .c-coral circle, .c-coral ellipse, .c-coral polygon { fill: #FAECE7; stroke: #993C1D; }
.c-pink rect, .c-pink circle, .c-pink ellipse, .c-pink polygon { fill: #FBEAF0; stroke: #993556; }
.c-gray rect, .c-gray circle, .c-gray ellipse, .c-gray polygon { fill: #F1EFE8; stroke: #5F5E5A; }
.c-blue rect, .c-blue circle, .c-blue ellipse, .c-blue polygon { fill: #E6F1FB; stroke: #185FA5; }
.c-green rect, .c-green circle, .c-green ellipse, .c-green polygon { fill: #EAF3DE; stroke: #3B6D11; }
.c-amber rect, .c-amber circle, .c-amber ellipse, .c-amber polygon { fill: #FAEEDA; stroke: #854F0B; }
.c-red rect, .c-red circle, .c-red ellipse, .c-red polygon { fill: #FCEBEB; stroke: #A32D2D; }
.th, text.th { font-weight: 500; fill: #212121; }
.ts, text.ts { font-size: 12px; fill: #6b7280; }
.t, text.t { font-size: 14px; fill: #212121; }
svg .arr { fill: none; stroke: #888780; stroke-width: 1.5; }
svg .leader { fill: none; stroke: #888780; stroke-width: 0.5; stroke-dasharray: 2 2; }
svg .box { fill: #f9f9f9; stroke: #e5e5e5; }
/* Claude CSS variable fallbacks */
:root {
--color-text-primary: #212121;
--color-text-secondary: #6b7280;
--color-border-primary: #e5e5e5;
--color-border-secondary: #e5e5e5;
--color-border-tertiary: #f0f0f0;
--color-background-primary: #ffffff;
--color-background-secondary: #fafafa;
--color-text-success: #059669;
--color-text-warning: #d97706;
--color-text-error: #dc2626;
}
</style>
</head>
<body>
<div id="widget-container">%%WIDGET_CODE%%</div>
<script>
window._widgetRendered = false;
</script>
%%INJECTED_SCRIPTS%%
<script>
(function() {
// Disable Chart.js animations globally
if (typeof Chart !== 'undefined') {
const orig = Chart.defaults;
if (orig.animation) orig.animation.duration = 0;
if (orig.animations) orig.animations.duration = 0;
}
function signalDone() {
window._widgetRendered = true;
if (window.parent) {
try { window.parent.postMessage({ type: 'XWX_WIDGET_READY' }, '*'); } catch(e) {}
}
}
if (document.getElementById('widget-container').innerHTML.includes('canvas')) {
setTimeout(signalDone, 1500);
} else {
requestAnimationFrame(function() { setTimeout(signalDone, 500); });
}
})();
</script>
</body>
</html>