Components / Controls
SelectionFrame
Move, resize and rotate one selected object with a mouse, pen, finger or the keyboard.
When to useLink to "When to use"
- Placing things on a page or canvas: form fields on a PDF, images, shapes, a crop area.
Use something else when:
- people reorder items in a list: SortableList
- people resize panes of a layout: SplitPane
UsageLink to "Usage"
import { SelectionFrame } from "@arshad-shah/cynosure";
<SelectionFrame label="Image" box={box} scale={zoom} resizable onChange={setPreview} onCommit={save} />Place the frame in a positioned layer over your page. box is in your own units and scale maps them to CSS pixels, so the same geometry works at any zoom. onChange previews each step of a drag or held key; onCommit marks the end of one change, which is one undo step. snap can adjust every proposed box.
KeyboardLink to "Keyboard"
| Keys | Action |
|---|---|
| Arrows | Move by step (Shift: largeStep) |
| Alt + arrows | Resize its own right and bottom edges (with resizable) |
[ and ] | Rotate 15° (with rotatable) |
| Escape | Cancel the key being held, or a drag, back to where it began |
| Enter | Commit the key being held |
Drawing a new boxLink to "Drawing a new box"
With draw, a drag anywhere on the layer draws a new box: a region select in a screenshot tool, a crop, an area on a grid. box starts as null. Before a box exists the layer is a focusable drawing area, and Enter places a box in its middle for keyboard users.
const [region, setRegion] = useState<FrameBox | null>(null);
<SelectionFrame label="Region" draw resizable box={region} bounds={page} onCommit={setRegion} />PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
labelRequired | Accessible name, e.g. "Text box: Hello". Describe the keys nearby with aria-describedby. | string | |
boxRequired | Where the object is, in your units (page points, canvas pixels). null before one is drawn (with draw). | FrameBox | null | |
onCommitRequired | The end of one change: pointer up, key up or Enter. One undo step. | (box: FrameBox, rotate: number) => void | |
draw | Draw a new box by dragging anywhere on the layer (a region select, a crop, a grid area). A press on the frame still moves it. With no box yet, the layer is focusable and Enter places one in the middle for the keyboard. | boolean | |
rotate | Degrees, clockwise. | number | |
scale | CSS pixels per unit (the zoom). Default 1. | number | 1 |
resizable | Show the eight resize handles; Alt+arrows resize too. | boolean | |
rotatable | Show the rotate handle; the [ and ] keys turn it by 15 degrees. | boolean | |
keepAspect | Keep the width-to-height ratio while resizing (Shift does it for one drag). | boolean | |
minSize | Smallest width and height, in units. Default 1. | number | 1 |
bounds | Keep the object inside this area (units). | { width: number; height: number; } | |
step | Arrow keys move (and Alt+arrows resize) by this many units; Shift by largeStep. Defaults 1 and 10. | number | 1 and 10 |
largeStep | Units the arrow keys move (and Alt+arrows resize) by with Shift held. Default 10. | number | 10 |
snap | Adjust every proposed box, e.g. snap to a grid or to other objects. | ((box: FrameBox) => FrameBox) | |
onChange | Every change while dragging or holding a key (a preview). | ((box: FrameBox, rotate: number) => void) | |
aria-describedby | Ids of text that describes the frame, such as its keys. | string | |
labels | Replace the built-in English text: how screen readers call the frame and the drawing area. | Partial<SelectionFrameLabels> | |
className | Added to the frame element, for layout. | string | |
style | Layout only. Restyle through --cy-selection-frame-* tokens. | CSSProperties |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
- Role: a focusable group named by
label, described to screen readers as a "selection" (labels.roleDescription). Describe the keys nearby witharia-describedby. - Pointer, pen and touch: through detent's pointer path; a finger held briefly drags, a quick swipe still scrolls the page; Escape cancels a drag.
- Rotation: handles turn with the object, and a drag is read in the object's own axes so the opposite edge stays where it is. Shift snaps rotation to 15°.
- Bounds: with
bounds, moving stops at the edges and resizing an unrotated object stops its grabbed edge there. - Touch: handles have a 44px hit area on touch screens; the rotate handle sits further out.
ThemingLink to "Theming"
Tokens: --cy-selection-frame-color and --cy-selection-frame-handle-size.
RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.