fix: convert style strings for react in the ops console

htm passes props through untouched and react rejects a style string with error
#62, so every view rendered an empty page. Converting once in the createElement
wrapper keeps plain css in the templates instead of style objects everywhere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnNxwxfXSbeNtjvtz5gayb
This commit is contained in:
ImBenji
2026-09-01 20:20:27 +01:00
co-authored by Claude Opus 5
parent 0a5b30ab63
commit 93108a27fe
+26 -1
View File
@@ -1,6 +1,31 @@
// Shared plumbing: htm binding, hash router, polling fetch, formatters.
const { createElement, useState, useEffect, useRef, useCallback } = React;
export const html = htm.bind(createElement);
// htm hands props straight through, and React refuses a style string (error #62).
// Writing style objects everywhere in tagged templates is miserable, so convert
// once here instead and let the views keep using plain css.
function cssToObject(css) {
const style = {};
for (const declaration of String(css).split(';')) {
const split = declaration.indexOf(':');
if (split === -1) continue;
const property = declaration.slice(0, split).trim();
const value = declaration.slice(split + 1).trim();
if (!property || !value) continue;
// custom properties have to stay verbatim, the rest camelCase
style[property.startsWith('--') ? property : property.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] = value;
}
return style;
}
function h(type, props, ...children) {
if (props && typeof props.style === 'string') {
return createElement(type, { ...props, style: cssToObject(props.style) }, ...children);
}
return createElement(type, props, ...children);
}
export const html = htm.bind(h);
export { useState, useEffect, useRef, useCallback };
export async function api(path, options = {}) {