getSessionGitStatus,
getSessionPaths,
} from './mockData';
export type ThemeType = 'light' | 'dark';
// The editor's stylesheet flattens every line number to one neutral colour
// (`--diffs-editor-line-number-fg`) and is injected as an unlayered <style>,
// so it overrides the library's per-line colouring (which lives in @layer
// base). We adopt this extra, higher-specificity unlayered sheet into the
// component, so it's created in an effect and torn down on session change.
function ChangesTree({
session,
activePath,
themeType,
onSelect,
}: {
session: AuiSession;
activePath: string | null;
themeType: ThemeType;
onSelect: (path: string) => void;
}) {
const containerRef = useRef<HTMLDivElement | null>(null);
const treeRef = useRef<FileTree | null>(null);
};
}, [session]);
// Inline color-scheme beats the tree's `:host { color-scheme: light dark }`,
// flipping its light-dark() colours with our toggle.
// pinning its light-dark() colours to the demo's dark mode.
useEffect(() => {
if (containerRef.current != null) {
containerRef.current.style.colorScheme = themeType;
containerRef.current.style.colorScheme = 'dark';
}
}, [themeType, session]);
}, [session]);
// Keep the highlighted row matched to the active file.
useEffect(() => {
const tree = treeRef.current;
return <div ref={containerRef} className="aui-tree" />;
}
export interface AgentUiProps {
// Theme is controlled by the parent so the toggle can live outside the
// component (the homepage section renders its own button group).
themeType: ThemeType;
// Highlight themes the surrounding worker pool was initialized with. Defaults
// to the shared homepage pool's themes.
theme?: { dark: string; light: string };
// Server-rendered diff HTML keyed by file path. When present the matching
// FileDiff hydrates from this markup (already syntax-highlighted) instead of
// waiting on the client worker, which also avoids an SSR/client mismatch.
prerenderedDiffs?: Record<string, string>;
}
export function AgentUi({
themeType,
theme = DEFAULT_THEMES,
prerenderedDiffs,
}: AgentUiProps) {
// The demo is always dark: the snapshot is prerendered dark and matching it
// avoids theme flashing, so there is no light/dark toggle.
export function AgentUi({ theme = DEFAULT_THEMES, prerenderedDiffs }: AgentUiProps) {
const session = AUI_SESSIONS[0];
const [activePath, setActivePath] = useState<string | null>(
() => session.changedFiles[0]?.path ?? null
: null,
[activeFile, editKey]
);
// Server-rendered, already-highlighted HTML for the active diff. The snapshot
// is generated in dark mode, so only reuse it while the demo is in dark mode
// (otherwise a freshly opened file would flash dark before re-highlighting).
// It's also only safe when the file is unedited so the markup matches
// `fileDiff`.
// Server-rendered, already-highlighted HTML for the active diff. Only safe
// when the file is unedited so the markup matches `fileDiff`.
const activePrerenderedHTML =
themeType === 'dark' &&
activePath != null &&
editsRef.current.get(editKey) == null
activePath != null && editsRef.current.get(editKey) == null
? prerenderedDiffs?.[activePath]
: undefined;
const breadcrumbSegments = activePath != null ? activePath.split('/') : [];
}, [activePath]);
return (
<EditProvider editor={editor}>
<div className="aui" data-theme-type={themeType} data-embedded="true">
<div className="aui" data-theme-type="dark" data-embedded="true">
<div className="aui-body">
<section className="aui-center">
<header className="aui-center-header">
<nav className="aui-breadcrumb" aria-label="File path">
fileDiff={fileDiff}
className="aui-surface"
options={{
theme,
themeType,
themeType: 'dark',
disableFileHeader: true,
overflow: 'wrap',
diffStyle: 'unified',
}}
</div>
<ChangesTree
session={session}
activePath={activePath}
themeType={themeType}
onSelect={openFile}
/>
</aside>
</div>