feat(web): replace flat lists with tree sidebar and object inspector
Add a containment-tree sidebar with class tags and display labels, plus an inspector pane backed by a viewer registry with a default viewer. Custom per-class viewers can be registered later.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import type { TTSObject } from '@tts/shared';
|
||||
|
||||
/**
|
||||
* A viewer renders a single selected object. Custom viewers can be registered
|
||||
* per object class (`Name`) and will take precedence over the default viewer.
|
||||
*/
|
||||
export interface ObjectViewer {
|
||||
/** The object class this viewer handles, e.g. `Card`, `Bag`. */
|
||||
name: string;
|
||||
component: (props: { object: TTSObject }) => ReactNode;
|
||||
}
|
||||
|
||||
const registry = new Map<string, ObjectViewer['component']>();
|
||||
|
||||
/** Register a viewer for a specific object class. */
|
||||
export function registerViewer(name: string, component: ObjectViewer['component']) {
|
||||
registry.set(name, component);
|
||||
}
|
||||
|
||||
/** Resolve the viewer for an object, falling back to the default viewer. */
|
||||
export function resolveViewer(object: TTSObject): ObjectViewer['component'] {
|
||||
return registry.get(object.Name) ?? DefaultViewer;
|
||||
}
|
||||
|
||||
/** The default viewer: a plain inspection of the object's fields. */
|
||||
export function DefaultViewer({ object }: { object: TTSObject }) {
|
||||
return (
|
||||
<dl className="grid grid-cols-1 gap-2 text-sm sm:grid-cols-2">
|
||||
{Object.entries(object).map(([key, value]) => (
|
||||
<div key={key} className="rounded-lg border border-zinc-800 bg-zinc-900 p-3">
|
||||
<dt className="font-mono text-xs uppercase text-zinc-500">{key}</dt>
|
||||
<dd className="mt-1 break-words text-zinc-200">
|
||||
{typeof value === 'string' || typeof value === 'number' ? (
|
||||
value
|
||||
) : (
|
||||
<pre className="whitespace-pre-wrap font-mono text-xs">
|
||||
{JSON.stringify(value, null, 2)}
|
||||
</pre>
|
||||
)}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user