import type { JSONArray, JSONObject, JSONValue } from "@vertesia/json"; import { DotBadge } from "@vertesia/ui/core"; import clsx from "clsx"; import { ReactNode } from "react"; import { computeTitleFromName } from "../form/ManagedObject.js"; interface JSONViewProps { value: JSONObject; } export function JSONView({ value }: JSONViewProps) { return
{ Object.entries(value).map(([key, value]) => ) }
} interface PropertyTitleProps { name: string; } function PropertyTitle({ name }: PropertyTitleProps) { return (
{computeTitleFromName(name)}
) } interface BlockElementProps { children: ReactNode | ReactNode[]; className?: string; } function BlockElement({ children, className }: BlockElementProps) { return (
{children}
) } interface PropertyElementProps { name: string; value: JSONValue; } function PropertyElement({ name, value }: PropertyElementProps) { const info = getValueInfo(value); switch (info.type) { case ValueType.Inline: return (

{info.value}

) case ValueType.Paragraph: return (

{info.value}

) case ValueType.Prose: return (
{info.value}
) case ValueType.Array: return ( ) case ValueType.Object: return (
{ Object.entries(value as JSONObject).map(([key, value]) => ) }
) } } interface ArrayPropertyProps { name?: string, value: JSONArray; } function ArrayProperty({ name, value }: ArrayPropertyProps) { const inlineLength = value.join(' ').length; const itemMediumLength = inlineLength / value.length; const isInline = (typeof value[0] === 'string') && (inlineLength < 80 || inlineLength < 400 && itemMediumLength < 32); const useBullet = value.length > 9; return isInline ? (
{name && } {value.map((item, index) => {String(item)})}
) : (
{name && }
{ (value as JSONArray).map((value, index) => ) }
) } interface ItemPropertyProps { index: number; value: JSONValue; useBullet?: boolean; } function ItemProperty({ index, value, useBullet }: ItemPropertyProps) { const bullet = useBullet ? : {index + 1}. const info = getValueInfo(value); let content; switch (info.type) { case ValueType.Object: content = { Object.entries(value as JSONObject).map(([key, value]) => ) } break; case ValueType.Array: content = ; break; case ValueType.Prose: content =
{info.value}
break; default: content =
{info.value}
break; } return (
{bullet}
{content}
) } enum ValueType { Inline, Paragraph, Prose, Array, Object } function getValueInfo(value: JSONValue): { value: any, type: ValueType } { if (value == null) { return { value: '-', type: ValueType.Inline } } if (Array.isArray(value)) { return { value, type: ValueType.Array } } const type = typeof value; if (type === 'string') { const len = (value as string).length; let type; if (len < 80) { type = ValueType.Inline; } else if (len > 400) { type = ValueType.Prose; } else { type = ValueType.Paragraph; value = (value as string).replace(/(?:\n\n)+/g, '\n\n') } return { type, value }; } else if (type === 'number' || type === 'boolean') { return { value: String(value), type: ValueType.Inline } } else { return { value, type: ValueType.Object } } }