Stepwise UI

Selection Frame

That box Figma draws around a selected frame - corner handles and a crisp accent stroke. Wrap it around a text span or any div to call it out. Square or circle handles, solid, dashed, or long-dashed lines, static or marching-ants animated. It measures its child, so it always fits.

Installation

npx stepwise-ui add selection-frame

Default

Consistent by Default
import { SelectionFrame } from '@/components/stepwise/selection-frame'

<SelectionFrame padding={6}>
  <span className="text-[28px] font-semibold">Consistent by Default</span>
</SelectionFrame>

Handles

Selectedsquare
Selectedcircle
<SelectionFrame handles="square">…</SelectionFrame>  // default
<SelectionFrame handles="circle">…</SelectionFrame>

Lines

dashed and long are tuned dash presets; pass dash to override either one's pattern directly.
solidsolid
dasheddashed
longlong
<SelectionFrame line="solid" />    // default
<SelectionFrame line="dashed" />   // dash [4, 4]
<SelectionFrame line="long" />     // dash [10, 6]

// override either preset's dash pattern directly
<SelectionFrame line="dashed" dash={[1, 3]} />

Animated

Dashed and long lines march; a solid line has no dash pattern to march, so animated only affects the corner handles' entrance for it. Leave animated off for a fully static frame.
Marching antsanimated · dashed
Long dashesanimated · long
// dashed / long → marching ants. Corner handles always pop in on mount.
<SelectionFrame animated line="dashed" />
<SelectionFrame animated line="long" color="#e11d48" handles="circle" />

Usage

Inline by default, so it drops straight into a headline or a sentence - the classic "circle the one word that matters" move. Pass inline={false} to wrap a block-level element like a card or an image instead.
Draw attention to what matters
<span className="text-[42px] font-semibold">
  Draw attention to what{' '}
  <SelectionFrame animated line="dashed" padding={4} handles="circle">
    matters
  </SelectionFrame>
</span>

Props

PropTypeDescription
children
React.ReactNode
The content to frame - it is measured live.
handles
"square" | "circle"
Corner handle shape. Default "square".
line
"solid" | "dashed" | "long"
Stroke style. Default "solid".
dash
[number, number]
Overrides the [dash, gap] px pair "dashed"/"long" resolve to.
animated
boolean
Marching ants for "dashed"/"long". Corner handles always animate in. Default false.
color
string
Accent color. Default Figma blue (#0d99ff).
radius
number
Frame corner radius. Default 0.
padding
number
Gap between content and frame. Default 4.
inline
boolean
Inline (text spans) vs block. Default true.