Iso Helpers
A set of isometric SVG primitives plus a self-contained showcase component. Use the primitives (IsoBox, IsoSlab, IsoCylinder) to compose hero illustrations and educational viz scenes; use the <IsoHelpers /> component to drop a labelled preview of all three into docs and design reviews.
The projection is the canonical 2:1 isometric — X-axis right-and-down (0.866, 0.5), Y-axis left-and-down (-0.866, 0.5), Z-axis straight up (0, -1). The isoToScreen(cx, cy, ix, iy, iz) helper does the conversion when you need to position custom geometry inside the same scene.
Installation
npx shadcn@latest add https://craftbits.dev/r/iso-helpers.jsonUsage
import { IsoHelpers } from "@craft-bits/edu";
<div className="text-cb-accent">
<IsoHelpers primitive="all" glow shadow />
</div>Compose your own scene with the underlying primitives:
import {
IsoBox,
IsoSlab,
IsoCylinder,
IsoGlowFilter,
isoToScreen,
} from "@craft-bits/edu/iso-helpers";Pin a label to an iso coordinate with isoToScreen:
const [lx, ly] = isoToScreen(200, 180, 0, 0, 48);Anatomy
- Root —
forwardRef<SVGSVGElement><svg>withviewBox="0 0 400 280". Spreads unknown SVG props. <defs>— registersIsoGlowFilterandIsoShadowFilterkeyed by auseId()stem, so multiple instances on the same page do not collide.IsoSlab— three-face thin box (defaulth=3) on the floor of the scene; usescb-bg-elevated/cb-bg-muted/cb-borderso it reads as the "ground".IsoBox— a vertical block on top of the slab, fills with the accent token at three opacities (1 / 0.72 / 0.5) so light hits the top, the left face goes mid, the right face goes shadow.IsoCylinder— top ellipse + curved-side path; the body usescb-accent-mutedand the cap usescb-infoso the iso scene shows multiple semantic colors at once.children— slot for custom SVG geometry (extra primitives, labels, overlays). Renders after the built-in primitives so it stacks on top.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
primitive | 'box' | 'slab' | 'cylinder' | 'all' | 'all' | Which primitive to feature. 'all' lays them out side-by-side. |
lift | number | 0 | Pivot the scene by this many units along the up (Z) axis. |
glow | boolean | false | Wrap primitives in the reusable glow filter. |
shadow | boolean | true | Apply the reusable drop-shadow filter to the scene. |
children | ReactNode | — | Extra SVG children rendered after the primitives. |
className | string | — | Merged onto the root <svg> via cn(). |
The IsoBox, IsoSlab, IsoCylinder, IsoGlowFilter, and IsoShadowFilter primitives are also exported from @craft-bits/edu; see the source for their individual props.
Accessibility
- The showcase
<svg>is decorative — it carriesaria-hidden="true"so screen readers skip past it. Parents that need a meaningful announcement should wrap the scene in a<figure>with a real caption. - No motion ships with the primitives; consumers that animate them must respect
prefers-reduced-motion: reducethemselves (useusePrefersReducedMotion()from@craft-bits/core). - The default glow flood color is
var(--cb-accent)and the default shadow flood color isvar(--cb-fg)— both adapt to light and dark themes without a hardcoded hex, satisfyingcraft-bits/no-pure-black-shadow. - Filter ids derive from
useId()so multiple<IsoHelpers />instances on the same page do not collide.
Credits
- Extracted from:
craftingattention(src/lessons/primitives/chrome/icons/heroes/iso-helpers.tsx). The source paired the primitives with a lesson-specificHeroSvgwrapper, a caller-supplieduidprop, and aCbag of color aliases pointing at--color-ink-*/--color-accent-*. craft-bits' version usesforwardRef<SVGSVGElement>+useId()for the filter chain, routes every color through a namedvar(--cb-*)token, and replaces the pure-black shadow flood withvar(--cb-fg)so the depth adapts to dark mode and stays inside the design-token palette.