SSocratic UI

Spatial Canvas

Open in playground

Place items on a two-axis canvas. Position encodes two dimensions at once — effort × impact, cost × value, risk × reward.

Preview

07

Map these on effort vs impact

Tap an item below, then tap the canvas to place it.

Usage

import { SpatialCanvas } from "@/components/socratic-ui/spatial-canvas";

const [value, setValue] = useState<Record<string, { x: number; y: number }>>({});

<SpatialCanvas
  question="Map these on effort vs impact"
  xAxisLabel="Effort"
  yAxisLabel="Impact"
  items={[
    { id: "a", title: "Onboarding flow" },
    { id: "b", title: "API docs" },
  ]}
  value={value}
  onChange={setValue}
/>

API Reference

PropTypeDefault
questionrequired

The headline shown above the canvas.

string—
subtitle

Optional supporting copy beneath the question.

string—
itemsrequired

Items the user can pick up and place on the canvas.

{ id: string; title: string; subtitle?: string }[]—
xAxisLabelrequired

Horizontal axis name (e.g. "Effort").

string—
yAxisLabelrequired

Vertical axis name (e.g. "Impact").

string—
xLowLabel

Optional low-end label for the X axis.

string—
xHighLabel

Optional high-end label for the X axis.

string—
yLowLabel

Optional low-end label for the Y axis.

string—
yHighLabel

Optional high-end label for the Y axis.

string—
valuerequired

Map of item id to normalized position. Both axes run 0 (low) to 1 (high); unplaced items are absent from the map.

Record<string, { x: number; y: number }>—
onChangerequired

Called whenever a position is placed, moved, or removed.

(value: Record<string, { x: number; y: number }>) => void—
number

Optional leading question number, e.g. "01".

string—
motion

Opt-in entrance animation config. Omit for static rendering; pass `{ enabled: true }` (or a preset from `motion.ts`) to animate in on mount.

SocraticMotion—