Fixes and responsive character sheet.

This commit is contained in:
2026-06-16 11:14:46 +02:00
parent bc1839c5e3
commit a5317d6156
5 changed files with 293 additions and 138 deletions

View File

@@ -1,6 +1,6 @@
import { buildIcon, getIcon, iconLoaded, loadIcon, type IconifyIcon } from 'iconify-icon';
import { loading } from './components';
import { _defer, raw, reactivity, type Proxy, type Reactive } from './reactive';
import { _defer, raw, reactivity, type Reactive } from './reactive';
export type Node = HTMLElement | SVGElement | Text | undefined;
export type NodeChildren = Array<Reactive<Node>> | undefined;
@@ -46,6 +46,7 @@ export function dom<T extends keyof HTMLElementTagNameMap, U extends any>(tag: T
{
const element = document.createElement(tag) as HTMLElementTagNameMap[T] & { array?: DOMList<U> };
const _cache = new Map<U, Node | Node[] | undefined>();
const seen = new Set<U>(); // Cache pruning utility
if(children)
{
@@ -83,10 +84,14 @@ export function dom<T extends keyof HTMLElementTagNameMap, U extends any>(tag: T
else
{
list.forEach(e => {
seen.add(e);
const child = raw(children.render(e, _cache.get(e)));
_cache.set(e, child);
append(element, child);
});
for (const key of _cache.keys()) if (!seen.has(key)) _cache.delete(key);
seen.clear();
}
})
}
@@ -226,7 +231,7 @@ const iconLoadingRegistry: Map<string, Promise<Required<IconifyIcon>> | null | u
export function icon(name: Reactive<string>, properties?: IconProperties)
{
const element = dom('div', { class: properties?.class, style: properties?.style });
let timeout: NodeJS.Timeout = setTimeout(() => {}, 0);
let timeout: NodeJS.Timeout = setTimeout(() => {}, 0), target: string;
const build = (icon: IconifyIcon | null | undefined) => {
if(!icon) return clearTimeout(timeout) ?? element.replaceChildren();
@@ -237,11 +242,12 @@ export function icon(name: Reactive<string>, properties?: IconProperties)
element.replaceChildren(dom);
}
reactivity(name, (name) => {
target = name;
if(!iconLoaded(name))
{
timeout = setTimeout(() => { element.replaceChildren(loading('small')); }, 100);
if(!iconLoadingRegistry.has(name)) iconLoadingRegistry.set(name, loadIcon(name));
iconLoadingRegistry.get(name)?.then(build);
iconLoadingRegistry.get(name)?.then((icon) => target === name && build(icon));
}
else build(getIcon(name));
})