@theoremjs/react 0.3.4-next.620.g9fe1aff → 0.3.4-next.624.g1a1ecd4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theoremjs/react",
3
- "version": "0.3.4-next.620.g9fe1aff",
3
+ "version": "0.3.4-next.624.g1a1ecd4",
4
4
  "description": "React bindings for Theorem: headless hooks + transport, an Astryx chat UI, and a Web-standard server handler.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -60,8 +60,8 @@
60
60
  "@stylexjs/stylex": "0.19.0",
61
61
  "react": "^19.0.0",
62
62
  "react-dom": "^19.0.0",
63
- "@theoremjs/agents": "^0.3.4-next.620.g9fe1aff",
64
- "@theoremjs/web": "^0.3.4-next.620.g9fe1aff"
63
+ "@theoremjs/agents": "^0.3.4-next.624.g1a1ecd4",
64
+ "@theoremjs/web": "^0.3.4-next.624.g1a1ecd4"
65
65
  },
66
66
  "peerDependenciesMeta": {
67
67
  "@astryxdesign/core": {
@@ -13,7 +13,7 @@ import { TextArea } from '@astryxdesign/core/TextArea';
13
13
  import { VStack } from '@astryxdesign/core/VStack';
14
14
  import { Children, createContext, use, useMemo, useRef, useState, useSyncExternalStore, } from 'react';
15
15
  import { useLabels } from "./labels-provider.js";
16
- import { PANEL_EDGE, PanelBody, PanelScroll, paneEdge, RAISED, SidePanel, SidePanelHeader, } from "./SidePanel.js";
16
+ import { PANEL_EDGE, PanelBody, PanelScroll, paneEdge, RaisedFrame, SidePanel, SidePanelHeader, } from "./SidePanel.js";
17
17
  import { textRows } from "./StateFields.js";
18
18
  import { WithTrace } from "./TraceInspectorPanel.js";
19
19
  import { CONSOLE_CARD } from "./trace-patterns.js";
@@ -39,7 +39,11 @@ function useNarrow() {
39
39
  * `wide` is a pair stacked on a narrow page, which takes the page's width.
40
40
  */
41
41
  function ConsoleSingle({ flush, wide, maxWidth, children, }) {
42
- return (_jsx(VStack, { height: "100%", paddingInlineStart: PANEL_EDGE, style: { ...(flush ? FLUSH_CARD : undefined), paddingInlineEnd: paneEdge(PANEL_EDGE) }, children: _jsx(Card, { variant: "transparent", height: "100%", padding: 0, style: flush ? { overflowY: 'auto' } : { ...RAISED, overflowY: 'auto' }, children: _jsx(Center, { axis: "horizontal", width: "100%", minHeight: "100%", children: _jsx(VStack, { width: "100%", maxWidth: wide ? undefined : maxWidth, gap: 3, padding: 4, children: children }) }) }) }));
42
+ const column = (_jsx(Center, { axis: "horizontal", width: "100%", minHeight: "100%", children: _jsx(VStack, { width: "100%", maxWidth: wide ? undefined : maxWidth, gap: 3, padding: 4, children: children }) }));
43
+ if (!flush)
44
+ return _jsx(RaisedFrame, { isScrollable: true, children: column });
45
+ // why: A flush page is already the raised panel, so it takes no block inset of its own.
46
+ return (_jsx(VStack, { height: "100%", paddingInlineStart: PANEL_EDGE, style: { ...FLUSH_CARD, paddingInlineEnd: paneEdge(PANEL_EDGE) }, children: _jsx(Card, { variant: "transparent", height: "100%", padding: 0, style: { overflowY: 'auto' }, children: column }) }));
43
47
  }
44
48
  /**
45
49
  * A console's page, for decisions and hosts alike: the trace toggle floats over
package/ui/SidePanel.d.ts CHANGED
@@ -22,12 +22,13 @@ export type SidePanelLabels = {
22
22
  resize: string;
23
23
  };
24
24
  /** Shows or hides one side panel (`panelId` from useSidePanel). */
25
- export declare function SidePanelToggle({ labels, icon, panelId, open, onToggle, }: {
25
+ export declare function SidePanelToggle({ labels, icon, panelId, open, onToggle, size, }: {
26
26
  labels: SidePanelLabels;
27
27
  icon: ReactNode;
28
28
  panelId: string;
29
29
  open: boolean;
30
30
  onToggle: () => void;
31
+ size?: 'sm';
31
32
  }): import("react").JSX.Element;
32
33
  export type SidePanelProps = {
33
34
  id?: string;
@@ -50,12 +51,6 @@ export type SidePanelProps = {
50
51
  className?: string;
51
52
  children?: ReactNode;
52
53
  };
53
- /** Page corners like the host's raised panels, no border or shadow; the card fill, so surface-filled cards read on it. */
54
- export declare const RAISED: {
55
- background: string;
56
- borderRadius: string;
57
- overflow: string;
58
- };
59
54
  /** A docked panel's inset: 12px off the outer edge, 16px off the bottom (the page inset). */
60
55
  export declare const PANEL_EDGE = 3;
61
56
  export declare const PANEL_BOTTOM = 4;
@@ -95,6 +90,11 @@ export declare function useWidth(): {
95
90
  ref: (node: HTMLDivElement | null) => (() => void) | undefined;
96
91
  width: number;
97
92
  };
93
+ /** The raised card a pane fills its place with, inset from every edge. */
94
+ export declare function RaisedFrame({ isScrollable, children, }: {
95
+ isScrollable?: boolean;
96
+ children: ReactNode;
97
+ }): import("react").JSX.Element;
98
98
  /**
99
99
  * A raised pane that fills its place, inset from the sides. Its content is
100
100
  * told whether the pane is wide enough for two readable columns.
package/ui/SidePanel.js CHANGED
@@ -45,12 +45,12 @@ export function SidePanelHeader({ children, floating = false, }) {
45
45
  return (_jsx(LayoutHeader, { hasDivider: false, children: _jsx(HStack, { hAlign: "end", gap: 1, children: children }) }));
46
46
  }
47
47
  /** Shows or hides one side panel (`panelId` from useSidePanel). */
48
- export function SidePanelToggle({ labels, icon, panelId, open, onToggle, }) {
48
+ export function SidePanelToggle({ labels, icon, panelId, open, onToggle, size, }) {
49
49
  const action = open ? labels.hide : labels.show;
50
- return (_jsx(IconButton, { label: action, tooltip: action, variant: open ? 'secondary' : 'ghost', "aria-expanded": open, "aria-controls": panelId, icon: icon, onClick: onToggle }));
50
+ return (_jsx(IconButton, { label: action, size: size, tooltip: action, variant: open ? 'secondary' : 'ghost', "aria-expanded": open, "aria-controls": panelId, icon: icon, onClick: onToggle }));
51
51
  }
52
52
  /** Page corners like the host's raised panels, no border or shadow; the card fill, so surface-filled cards read on it. */
53
- export const RAISED = {
53
+ const RAISED = {
54
54
  background: 'var(--theorem-pane-background, var(--color-background-card))',
55
55
  borderRadius: 'var(--radius-page)',
56
56
  overflow: 'hidden',
@@ -100,16 +100,20 @@ export function useWidth() {
100
100
  }, []);
101
101
  return { ref, width };
102
102
  }
103
+ /** The raised card a pane fills its place with, inset from every edge. */
104
+ export function RaisedFrame({ isScrollable = false, children, }) {
105
+ return (_jsx(VStack, { height: "100%", paddingInlineStart: PANEL_EDGE, paddingBlockStart: PANEL_EDGE, style: {
106
+ paddingInlineEnd: paneEdge(PANEL_EDGE),
107
+ paddingBlockEnd: paneEdge(PANEL_EDGE),
108
+ }, children: _jsx(Card, { variant: "transparent", height: "100%", padding: 0, style: isScrollable ? { ...RAISED, overflowY: 'auto' } : RAISED, children: children }) }));
109
+ }
103
110
  /**
104
111
  * A raised pane that fills its place, inset from the sides. Its content is
105
112
  * told whether the pane is wide enough for two readable columns.
106
113
  */
107
114
  export function RaisedPane({ id, header, children, }) {
108
115
  const { ref, width } = useWidth();
109
- return (_jsx(Layout, { height: "fill", style: { position: 'relative' }, header: header, content: _jsx(LayoutContent, { padding: 0, isScrollable: false, children: _jsx(VStack, { height: "100%", paddingInlineStart: PANEL_EDGE, paddingBlockStart: PANEL_EDGE, style: {
110
- paddingInlineEnd: paneEdge(PANEL_EDGE),
111
- paddingBlockEnd: paneEdge(PANEL_EDGE),
112
- }, children: _jsx(Card, { variant: "transparent", height: "100%", padding: 0, style: RAISED, children: _jsx("div", { id: id, ref: ref, style: { height: '100%' }, children: children(isSidePanelWide(width)) }) }) }) }) }));
116
+ return (_jsx(Layout, { height: "fill", style: { position: 'relative' }, header: header, content: _jsx(LayoutContent, { padding: 0, isScrollable: false, children: _jsx(RaisedFrame, { children: _jsx("div", { id: id, ref: ref, style: { height: '100%' }, children: children(isSidePanelWide(width)) }) }) }) }));
113
117
  }
114
118
  /** A raised pane's content. Narrow, the detail takes the overview's place; wide, it sits beside it. */
115
119
  export function PaneLayout({ isWide, label, detailLabel, lead, overview, detail, }) {
@@ -2,9 +2,11 @@ import type { TraceRecord } from '@theoremjs/agents';
2
2
  import type { TraceFeed } from '@theoremjs/web/client';
3
3
  import { type ReactNode } from 'react';
4
4
  /** The inspector over the records a feed has delivered; the panel loads this module when it first opens. */
5
- export declare function TraceFeedBody({ traces, isWide, }: {
5
+ export declare function TraceFeedBody({ traces, isWide, end, }: {
6
6
  traces: TraceFeed | undefined;
7
7
  isWide: boolean;
8
+ /** Drawn after the turn arrows: the panel's toggle. */
9
+ end?: ReactNode;
8
10
  }): import("react").JSX.Element;
9
11
  /**
10
12
  * Only what the records say of guardrails: how long the checks took, how many
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Badge } from '@astryxdesign/core/Badge';
3
3
  import { EmptyState } from '@astryxdesign/core/EmptyState';
4
4
  import { HStack } from '@astryxdesign/core/HStack';
@@ -143,9 +143,9 @@ function TurnOverview({ turns, index, onPick, onBack, selectedId, onSelect, end,
143
143
  const tools = traceSpans([root]).filter((node) => node.meta.type === 'tool').length;
144
144
  return (_jsxs(VStack, { gap: 5, padding: 4, children: [_jsx(TurnPicker, { turns: turns, index: index, onChange: onPick, onBack: onBack, end: end }), _jsxs(VStack, { gap: 3, children: [_jsx(TurnStats, { totals: turn.totals, tools: tools, latency: latency }), _jsx(TraceCharts, { root: root, split: turn.split, onSelect: onSelect })] }), _jsxs(VStack, { gap: 2, children: [_jsx(SectionTitle, { title: t('@theorem.panel.trace.timeline') }), _jsx(PowerSearch, { config: config, filters: filters, onChange: setFilters, label: t('@theorem.panel.trace.search'), isLabelHidden: true, placeholder: t('@theorem.panel.trace.search.placeholder'), resultCount: matches?.size, size: "sm" }), _jsx(TraceWaterfall, { root: root, selectedId: selectedId, matches: matches, onSelect: onSelect }, root.id)] }), story.length > 0 ? (_jsxs(VStack, { gap: 2, children: [_jsx(SectionTitle, { title: t('@theorem.panel.trace.story') }), _jsx(TraceStory, { steps: story, selectedId: selectedId, matches: matches, onSelect: onSelect })] })) : null, guardrails.length > 0 ? (_jsxs(VStack, { gap: 2, children: [_jsx(SectionTitle, { title: t('@theorem.panel.trace.guardrails') }), _jsx(TraceGuardrails, { checks: guardrails, onSelect: onSelect })] })) : null] }));
145
145
  }
146
- function EmptyTrace() {
146
+ function EmptyTrace({ end }) {
147
147
  const { t } = useTraceFormat();
148
- return (_jsx(VStack, { height: "100%", vAlign: "center", padding: 4, children: _jsx(EmptyState, { icon: _jsx(Icon, { icon: IconActivity, size: "lg", color: "secondary" }), title: t('@theorem.panel.trace.empty.title'), description: t('@theorem.panel.trace.empty.description'), isCompact: true }) }));
148
+ return (_jsxs(VStack, { height: "100%", vAlign: "center", padding: 4, children: [end ? _jsx(HStack, { justify: "end", children: end }) : null, _jsx(EmptyState, { icon: _jsx(Icon, { icon: IconActivity, size: "lg", color: "secondary" }), title: t('@theorem.panel.trace.empty.title'), description: t('@theorem.panel.trace.empty.description'), isCompact: true })] }));
149
149
  }
150
150
  /** The open span of the open turn; opening another turn closes it. */
151
151
  function useOpenSpan(turns) {
@@ -207,19 +207,19 @@ function TraceDownload({ records }) {
207
207
  * The panel's content. Narrow, the turn fills it and a span opens in its
208
208
  * place; wide, an open span sits beside the turn.
209
209
  */
210
- function TraceInspectorBody({ records, isWide, }) {
210
+ function TraceInspectorBody({ records, isWide, end, }) {
211
211
  const tree = useMemo(() => traceTree(records), [records]);
212
212
  const turns = useMemo(() => traceTurns(tree), [tree]);
213
213
  const { t } = useTraceFormat();
214
214
  const { index, root, open, select, close, pick } = useOpenSpan(turns);
215
215
  if (turns.length === 0)
216
- return _jsx(EmptyTrace, {});
217
- const overview = (_jsx(Overview, { turns: turns, index: index, pick: pick, selectedId: open?.id, select: select, end: _jsx(TraceDownload, { records: records }) }));
216
+ return _jsx(EmptyTrace, { end: end });
217
+ const overview = (_jsx(Overview, { turns: turns, index: index, pick: pick, selectedId: open?.id, select: select, end: _jsxs(_Fragment, { children: [_jsx(TraceDownload, { records: records }), end] }) }));
218
218
  return (_jsx(PaneLayout, { isWide: isWide, label: t('@theorem.panel.trace.name'), detailLabel: open?.meta.label ?? '', lead: _jsx(TracePatterns, {}), overview: overview, detail: open && (_jsx(SpanPane, { open: open, turnStartMs: root?.startMs ?? 0, isWide: isWide, onBack: close, onOpen: select })) }));
219
219
  }
220
220
  /** The inspector over the records a feed has delivered; the panel loads this module when it first opens. */
221
- export function TraceFeedBody({ traces, isWide, }) {
222
- return _jsx(TraceInspectorBody, { records: useTraceRecords(traces), isWide: isWide });
221
+ export function TraceFeedBody({ traces, isWide, end, }) {
222
+ return _jsx(TraceInspectorBody, { records: useTraceRecords(traces), isWide: isWide, end: end });
223
223
  }
224
224
  /**
225
225
  * Only what the records say of guardrails: how long the checks took, how many
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Icon } from '@astryxdesign/core/Icon';
3
3
  import { IconActivity } from '@tabler/icons-react';
4
4
  import { cloneElement, createContext, isValidElement, lazy, Suspense, use, useCallback, useId, useRef, useState, } from 'react';
@@ -13,8 +13,8 @@ const TracePlacementContext = createContext('replace');
13
13
  export function TracePlacement({ value, children, }) {
14
14
  return _jsx(TracePlacementContext, { value: value, children: children });
15
15
  }
16
- function TraceView({ id, header, traces, }) {
17
- return (_jsx(RaisedPane, { id: id, header: header, children: (isWide) => (_jsx(Suspense, { fallback: null, children: _jsx(TraceFeedBody, { traces: traces, isWide: isWide }) })) }));
16
+ function TraceView({ id, toggle, traces, }) {
17
+ return (_jsx(RaisedPane, { id: id, children: (isWide) => (_jsx(Suspense, { fallback: _jsx(SidePanelHeader, { floating: true, children: toggle }), children: _jsx(TraceFeedBody, { traces: traces, isWide: isWide, end: toggle }) })) }));
18
18
  }
19
19
  /**
20
20
  * The trace inspector, offered when the profile records traces. By default the
@@ -39,21 +39,21 @@ export function useTraceInspector(iface, traces, open) {
39
39
  if (iface.observability?.record !== true)
40
40
  return { toggle: null, view: null, labels, offered: false };
41
41
  const isOpen = open ?? own;
42
- const toggle = open === undefined ? (_jsx(SidePanelToggle, { labels: labels, icon: _jsx(Icon, { icon: IconActivity }), panelId: id, open: isOpen, onToggle: () => setOwn((value) => !value) })) : null;
43
- const view = isOpen ? openTrace(placement === 'panel', id, traces, toggle) : null;
42
+ const toggleOf = (size) => open === undefined ? (_jsx(SidePanelToggle, { labels: labels, icon: _jsx(Icon, { icon: IconActivity }), panelId: id, open: isOpen, size: size, onToggle: () => setOwn((value) => !value) })) : null;
43
+ const toggle = toggleOf();
44
+ const view = isOpen ? openTrace(placement === 'panel', id, traces, toggleOf('sm')) : null;
44
45
  return { toggle, view, labels, offered: true };
45
46
  }
46
- /** The open trace: filling the host's docked panel, or as its own panel; the toggle on top. */
47
+ /** The open trace: filling the host's docked panel, or as its own panel; the toggle sits in its top row. */
47
48
  function openTrace(docked, id, traces, toggle) {
48
- const header = toggle ? _jsx(SidePanelHeader, { floating: true, children: toggle }) : null;
49
49
  if (docked)
50
- return _jsx(TraceFill, { id: id, header: header, traces: traces });
51
- return _jsx(TraceView, { id: id, header: header, traces: traces });
50
+ return _jsx(TraceFill, { id: id, toggle: toggle, traces: traces });
51
+ return _jsx(TraceView, { id: id, toggle: toggle, traces: traces });
52
52
  }
53
53
  /** The trace body, filling the docked panel. The panel supplies the raised card. */
54
- function TraceFill({ id, header, traces, }) {
54
+ function TraceFill({ id, toggle, traces, }) {
55
55
  const { ref, width } = useWidth();
56
- return (_jsxs("div", { id: id, ref: ref, style: { height: '100%', position: 'relative' }, children: [header, _jsx(Suspense, { fallback: null, children: _jsx(TraceFeedBody, { traces: traces, isWide: isSidePanelWide(width) }) })] }));
56
+ return (_jsx("div", { id: id, ref: ref, style: { height: '100%', position: 'relative' }, children: _jsx(Suspense, { fallback: _jsx(SidePanelHeader, { floating: true, children: toggle }), children: _jsx(TraceFeedBody, { traces: traces, isWide: isSidePanelWide(width), end: toggle }) }) }));
57
57
  }
58
58
  /** The surface, with the trace docked at its inline end. A host-driven trace stays in place. */
59
59
  function TraceDock({ inspector, children }) {