diff --git a/cmd/web-ui/static/modules/components.js b/cmd/web-ui/static/modules/components.js new file mode 100644 index 0000000..7eae4d1 --- /dev/null +++ b/cmd/web-ui/static/modules/components.js @@ -0,0 +1,102 @@ +// ── components.js — shared UI primitives ───────────────── +// +// One-stop helpers for the repeating bar / pill / chart-header +// patterns across pages. Renderers return HTML strings — callers +// inject via innerHTML and wire events on the resulting DOM. + +import { escapeHTML } from './utils.js'; + +// ── Bar primitives ─────────────────────────────────────── + +// barTrack — just the percentage bar (no label/count head). +// value: numeric value to display +// max: ceiling for percentage; 0/falsy means 0% +// fwClass: optional framework slug (openclaw, claude-code, hermes, …) +// — applied as fw- on the fill for color +// size: 'xs' | 'sm' | 'md' | 'lg' (default 'md') +// modifier: extra class on the fill (e.g. 'model', 'input', 'output') +export function barTrack({ value = 0, max = 0, fwClass = '', size = 'md', modifier = '' } = {}) { + const pct = max > 0 ? Math.min(100, (value / max) * 100).toFixed(1) : '0'; + const fillClasses = ['am-bar-fill']; + if (fwClass) fillClasses.push('fw-' + fwClass); + if (modifier) fillClasses.push(modifier); + return `
`; +} + +// barRow — head (name + count) plus track. +// countDisplay overrides the rendered count text (e.g. "238" vs "238 events"). +export function barRow({ name = '', count = 0, countDisplay, max = 0, fwClass = '', size = 'sm', modifier = '' } = {}) { + const display = countDisplay != null ? countDisplay : count; + return ` +
+
+ ${escapeHTML(String(name))} + ${escapeHTML(String(display))} +
+ ${barTrack({ value: count, max, fwClass, size, modifier })} +
`; +} + +// barRankList — ranked list of barRows wrapped in