diff --git a/docs/app/global.css b/docs/app/global.css index ac4955f41..5b5ce27a8 100644 --- a/docs/app/global.css +++ b/docs/app/global.css @@ -152,3 +152,11 @@ body { padding-top: 4rem !important; } } + +.paste-loading { + display: flex; + align-items: center; + justify-content: center; + color: var(--openui-text-neutral-secondary); + height: 100vh; +} diff --git a/docs/app/paste/components/Banner.tsx b/docs/app/paste/components/Banner.tsx new file mode 100644 index 000000000..e5bb4ab60 --- /dev/null +++ b/docs/app/paste/components/Banner.tsx @@ -0,0 +1,17 @@ +"use client"; + +import { Callout } from "@openuidev/react-ui"; + +export function Banner({ + tone, + children, +}: { + tone: "warning" | "danger" | "info"; + children: React.ReactNode; +}) { + return ( +
+ Paste is a playground for OpenUI Lang. Paste code on the left; the + panels on the right show what the parser and renderer make of it. +
+ +Query() calls resolve with mocked data (any tool name returns sample
+ data; calls are logged under the canvas). Always rendered with the bundled
+ renderer; the selected lang-core version drives the other panels.
+ + Stream replays your code as if an LLM were emitting it.{" "} + LLM-like chunking adds realistic jitter and stalls (reproducible via{" "} + Seed). Watch the render window build up live, pause and{" "} + Step chunk by chunk, and check whether the root ever appears or + drops mid-stream. +
+{this.state.error.message}
+ {this.props.hint && {this.props.hint}
} + ++ Result is {(json.length / 1024).toFixed(0)} KB.{" "} + +
+{json}
+ + Rendered with bundled lang-core {BUNDLED_LANG_CORE_VERSION} — validation uses v + {selectedVersion}. +
+ )} + {usesTools && ( +
+ Query() and Mutation() run against a{" "}
+ mock tool provider: any tool name resolves with sample data after
+ ~400ms. Calls are logged below the canvas.
+
+
{c.tool}({safeDescribe(c.args)}) → sample data
+ {e.code} {e.message}
+ {e.hint && {e.hint}
} +{actionLog.join("\n")}
+ {JSON.stringify(formState, null, 2)}
+ {state.fatal}
+ Trace capped at 5,000 rows — remaining chunks not logged.
+ )} +| # | +chunk | +delay | +root | +stmts | +state | +unres | +errs | +
|---|---|---|---|---|---|---|---|
| {row.i} | +
+ {visualize(row.chunkPreview)}
+ |
+ {row.delayMs}ms | +
+ {row.rootAppeared ? (
+ <>
+ |
+ {row.statementCount} | +{row.incomplete ? "incomplete" : "complete"} | +{row.unresolvedCount} | +{row.errorCount} | +
{safeStringify(value)};
+ }
+ if (isExprLike(value)) {
+ return ⟨{(value as { type: string }).type}⟩;
+ }
+ return {safeStringify(value)};
+}
+
+function safeStringify(v: unknown): string {
+ try {
+ const s = JSON.stringify(v);
+ return s && s.length > 120 ? `${s.slice(0, 120)}…` : (s ?? String(v));
+ } catch {
+ return String(v);
+ }
+}
+
+function NodeView({ node }: { node: { typeName: string; props: Record{safeStringify(v)}
+ {safeStringify(queries)}
+ {safeStringify(mutations)}
+ {fatal}
+ This can happen on old lang-core versions with a different API surface.
+{code} ({errors.length})
+ {e.component}
+ {e.path}
+ {e.statementId && {e.message}
+ {hint && ( +
+