fix: make architecture semantic zoom readable
This commit is contained in:
@@ -186,6 +186,8 @@ describe("InteractiveFigure", () => {
|
|||||||
renderFigure({ focusPath: [], size: "stage" });
|
renderFigure({ focusPath: [], size: "stage" });
|
||||||
const figure = screen.getByRole("group", { name: /architecture/i });
|
const figure = screen.getByRole("group", { name: /architecture/i });
|
||||||
expect(figure).toHaveAttribute("data-figure-size", "stage");
|
expect(figure).toHaveAttribute("data-figure-size", "stage");
|
||||||
|
expect(figure).toHaveAttribute("data-figure-layout", "layered");
|
||||||
|
expect(figure).toHaveAttribute("data-figure-focus-level", "0");
|
||||||
expect(figure.querySelector(".interactive-figure__canvas")).toBeInTheDocument();
|
expect(figure.querySelector(".interactive-figure__canvas")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -205,6 +207,7 @@ describe("InteractiveFigure", () => {
|
|||||||
"data-pan-zoom",
|
"data-pan-zoom",
|
||||||
"enabled",
|
"enabled",
|
||||||
);
|
);
|
||||||
|
expect(screen.getByRole("group", { name: /runtime detail/i })).toHaveAttribute("data-figure-focus-level", "1");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resets roving focus when focusPath changes", () => {
|
it("resets roving focus when focusPath changes", () => {
|
||||||
|
|||||||
@@ -230,6 +230,8 @@ const InteractiveFigureInner = ({
|
|||||||
data-motion={motionDisabled ? "disabled" : "enabled"}
|
data-motion={motionDisabled ? "disabled" : "enabled"}
|
||||||
data-figure-id={focus.figure.id}
|
data-figure-id={focus.figure.id}
|
||||||
data-figure-size={size}
|
data-figure-size={size}
|
||||||
|
data-figure-layout={focus.figure.layout.kind}
|
||||||
|
data-figure-focus-level={focus.path.length}
|
||||||
data-pan-zoom={graphInspectionEnabled ? "enabled" : "disabled"}
|
data-pan-zoom={graphInspectionEnabled ? "enabled" : "disabled"}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
>
|
>
|
||||||
@@ -237,6 +239,8 @@ const InteractiveFigureInner = ({
|
|||||||
breadcrumbs={focus.breadcrumbs}
|
breadcrumbs={focus.breadcrumbs}
|
||||||
onNavigate={handleBreadcrumbNavigate}
|
onNavigate={handleBreadcrumbNavigate}
|
||||||
/>
|
/>
|
||||||
|
{/* React Flow must measure nodes in its unscaled coordinate space. Keep
|
||||||
|
this canvas responsive instead of reintroducing a CSS scale wrapper. */}
|
||||||
<div className="interactive-figure__canvas" ref={containerRef}>
|
<div className="interactive-figure__canvas" ref={containerRef}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={rfNodes}
|
nodes={rfNodes}
|
||||||
|
|||||||
@@ -151,6 +151,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.interactive-figure[data-figure-size="stage"][data-figure-layout="flow"] .interactive-figure__canvas {
|
||||||
|
min-width: 72rem;
|
||||||
|
}
|
||||||
|
|
||||||
.interactive-figure[data-figure-size="stage"] .react-flow {
|
.interactive-figure[data-figure-size="stage"] .react-flow {
|
||||||
border: 1px solid color-mix(in oklch, var(--color-editorial-muted, oklch(0.48 0.025 65)) 42%, transparent);
|
border: 1px solid color-mix(in oklch, var(--color-editorial-muted, oklch(0.48 0.025 65)) 42%, transparent);
|
||||||
border-radius: 0.65rem;
|
border-radius: 0.65rem;
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ describe("ArchitectureScene", () => {
|
|||||||
renderArchitecture({ focusPath: [] });
|
renderArchitecture({ focusPath: [] });
|
||||||
expect(screen.getByRole("group", { name: /architecture/i })).toHaveAttribute("data-figure-size", "stage");
|
expect(screen.getByRole("group", { name: /architecture/i })).toHaveAttribute("data-figure-size", "stage");
|
||||||
expect(screen.getByTestId("architecture-scene")).toHaveAttribute("data-visual-pass", "architecture-stage");
|
expect(screen.getByTestId("architecture-scene")).toHaveAttribute("data-visual-pass", "architecture-stage");
|
||||||
|
expect(screen.getByTestId("architecture-scene")).toHaveAttribute("data-architecture-focus", "system");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a directly linked nested provider view", () => {
|
it("renders a directly linked nested provider view", () => {
|
||||||
@@ -94,5 +95,7 @@ describe("ArchitectureScene", () => {
|
|||||||
expect(screen.getByRole("group", { name: /configured providers/i })).toBeInTheDocument();
|
expect(screen.getByRole("group", { name: /configured providers/i })).toBeInTheDocument();
|
||||||
expect(screen.getByText("MCP sources")).toBeInTheDocument();
|
expect(screen.getByText("MCP sources")).toBeInTheDocument();
|
||||||
expect(screen.getByText("Python sources")).toBeInTheDocument();
|
expect(screen.getByText("Python sources")).toBeInTheDocument();
|
||||||
|
expect(screen.getByTestId("architecture-scene")).toHaveAttribute("data-architecture-focus", "nested");
|
||||||
|
expect(screen.getByRole("group", { name: /configured providers/i })).toHaveAttribute("data-figure-focus-level", "2");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,7 +31,13 @@ export const ArchitectureScene = ({
|
|||||||
: architectureCatalog;
|
: architectureCatalog;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="architecture-scene" data-testid="architecture-scene" data-visual-pass="architecture-stage">
|
<section
|
||||||
|
className="architecture-scene"
|
||||||
|
data-testid="architecture-scene"
|
||||||
|
data-visual-pass="architecture-stage"
|
||||||
|
data-focus-level={focusPath.length}
|
||||||
|
data-architecture-focus={focusPath.length === 0 ? "system" : "nested"}
|
||||||
|
>
|
||||||
<StageCaption eyebrow={`Act II · ${scene.claimClass}`} title={scene.title}>
|
<StageCaption eyebrow={`Act II · ${scene.claimClass}`} title={scene.title}>
|
||||||
<p>{beat.caption}</p>
|
<p>{beat.caption}</p>
|
||||||
</StageCaption>
|
</StageCaption>
|
||||||
|
|||||||
Reference in New Issue
Block a user