Direction sphere
FreeA direction input shaped like what it controls. Drag a light across a sphere and a sample beside it takes the highlight and drop shadow of that light. Two sliders carry the same two numbers, so the sphere is a convenience and never the only way in.
pnpm dlx shadcn@latest add @caliper/direction-sphere315° azimuth 48° elevation
When to use #
Use it for
- Light and shadow direction in a design tool, an emboss or a drop-shadow editor.
- Any value that is two angles, such as azimuth and elevation.
Skip it when
- A single angle; use a dial or a slider.
- Exact placement of a point on a plane; use two number fields.
Decisions #
Why it is built this way, so you know what to keep when you change your copy.
Behaviour
- The sliders are the accessible input
- Azimuth runs 0 to 359 and elevation 5 to 90, each a native range with value text. The sphere takes the arrow keys as well, 5 degrees a press and 15 with Shift.
- The numbers are always written
- The readout names both angles in degrees, so the picture never carries the value alone.
Styling
- The sphere is shaded by the light it sets
- The middle is light from straight on and the rim is light from the side. Dragging has no easing, so reduced motion changes nothing.
Installation #
pnpm dlx shadcn@latest add @caliper/direction-sphere
Adds its 6 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { DirectionSphere } from "@/components/ui/direction-sphere" export function DirectionSphereDemo() { return ( <div className="w-full max-w-2xl"> <DirectionSphere label="Light direction" /> </div> ); }
API reference #
DirectionSphere
component
Accessibility #
It exposes group semantics, with aria-roledescription, aria-label, aria-live and aria-valuetext kept in step with state. Changes that matter are announced through a live region.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.