# Value grip

A React component in [Beamline](https://beamline.io/)'s [Form controls](https://beamline.io/components/forms) category. Live demo: https://beamline.io/components/value-grip

A grip on a scale your screen draws (a bar's end, a flag, a markup's edge): drag it, or use the arrows, to a value snapped to its step; the value arrives live while held and is committed once on letting go, Escape puts back the value from the press, and screen readers hear it as a slider with the value in your words.

## Use it for

- A quantity your screen already draws (a lead time on a runway, a markup on a cost bar, a deadline flag): make the drawing the control instead of a typed field, with the field kept as the exact twin.
- Several grips on one drawing that each move their own value, with the scale held still while one is held.

## Not for

- A stand-alone range input with its own track ([slider](https://beamline.io/components/slider)).
- Scrubbing through time or a recording (scrubber, [replay-bar](https://beamline.io/components/replay-bar)).
- Moving whole items between places (drag-and-drop lists, [kanban-board](https://beamline.io/components/kanban-board)).

## Anatomy

- handle: spans the host's track and is moved to the value by transform
- thumb (role slider): a 24 px hit on the value (44 px under a finger), drawn as an upright ink bar (bar) or only as its hover and focus (bare, over a mark the host draws)

## States

- rest: placed by CSS from the value
- hover: a ring around the bar, or a tint over a bare mark
- focus: the focus ring on the thumb
- held (data-state=held): no glide, the value follows the hand per step; the host is told (onHoldChange) to hold its scale still
- released: onValueCommit once
- cancelled (Escape, a lost pointer): the value from the press comes back through onValueChange, no commit
- keyboard step: onValueChange and onValueCommit together
- disabled: no hand, not in the tab order
- right to left: the scale and the arrow keys mirror
- reduced motion: no glide after a key or a commit

## Keyboard

- Left/Right (mirrored right to left) and Down/Up: one step
- Shift with an arrow, or Page Up/Down: the big step
- Home/End: the limits
- Escape during a drag: back to the value at the press

## Motion

Between values set by a key or by the host the handle glides by transform with the considered duration; while held it follows the hand in the same frame (no transition). Nothing runs at rest; reduced motion places it at once.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` (required) | `number` | — | The value the grip stands on, in the scale's units (days, dollars, a rate). |
| `scale` (required) | `{ from: number; to: number; }` | — | What the track's start and end stand for. The grip is placed at `(value - from) / (to - from)` of the track. Hold the scale still while the grip is held (`onHoldChange`), so nothing under the hand moves. |
| `track` (required) | `RefObject<HTMLElement \| null>` | — | The element the scale is drawn across; read once at the press, never during the drag. |
| `step` | `number` | — | Units per step (7 for a week of days, 0.5 for half a percent). Default 1. |
| `bigStep` | `number` | — | Units per Shift step and Page Up/Down. Default 10 steps. |
| `origin` | `number` | — | Where steps count from (a lead time's start): values snap to `origin + n × step`. Default 0. |
| `min` (required) | `number` | — |  |
| `max` (required) | `number` | — |  |
| `label` (required) | `string` | — | The grip's name ("Lead time", "Markup on labour"). |
| `valueText` | `string` | — | The value in words, with what it does ("9 weeks: arrives Jan 23, 1 day late"). Default: the number. |
| `onValueChange` | `((value: number) => void)` | — | Every step while held, and every key step: redraw from it. |
| `onValueCommit` | `((value: number) => void)` | — | Once, on letting go or after a key step: save it. Not called on Escape. |
| `onHoldChange` | `((held: boolean) => void)` | — | Held or let go: freeze the scale and stop gliding while held. |
| `appearance` | `"bar" \| "bare"` | — | `bar` draws an upright ink bar on the value (a bar's end); `bare` draws nothing but the hover and focus (the host already draws a mark there, such as a flag). Default bar. |
| `disabled` | `boolean` | — |  |
| `className` | `string` | — | Classes on the documented visual root; no override by default. |
| `style` | `CSSProperties` | — | Inline styles on the documented visual root; no overrides by default. |
| `ref` | `Ref<HTMLSpanElement>` | — | Receives the documented native target or imperative handle; omitted by default. |

## Used in

- [Action center](https://beamline.io/components/action-center.md)
- [Audience segments](https://beamline.io/components/audience-segments.md)
- [Billing desk](https://beamline.io/components/billing-desk.md)
- [Services and hours](https://beamline.io/components/booking-setup.md)
- [Captions](https://beamline.io/components/captions.md)
- [Change orders](https://beamline.io/components/change-orders.md)
- [Dispensing](https://beamline.io/components/dispensing.md)
- [Gift desk](https://beamline.io/components/gift-desk.md)
- [Lease setup](https://beamline.io/components/lease-setup.md)
- [Maintenance plans](https://beamline.io/components/maintenance-plans.md)
- [Packages & memberships](https://beamline.io/components/packages-memberships.md)
- [Purchase orders](https://beamline.io/components/purchase-orders.md)
- [Rooms & equipment](https://beamline.io/components/resource-setup.md)
- [Return case](https://beamline.io/components/return-case.md)
- [Run of show](https://beamline.io/components/run-of-show.md)
- [Submittal register](https://beamline.io/components/submittal-register.md)

## Import

```tsx
import { ValueGrip } from "@beamline/value-grip";
```

## Get it

Value grip is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. [Get Beamline](https://beamline.io/checkout?pack=complete) · [Connect your agent](https://beamline.io/connect)

## More in Form controls

- [Target table](https://beamline.io/components/target-table): Rows of repeated rounds with typed targets (a load × a count, a count range, a time, a load held for a time), each row drawn as a bar beside its numbers…
- [Color Palette](https://beamline.io/components/color-palette): A wheel of preset colours to pick from: twelve hues around the ring, their tints inward, white at the middle; the chosen swatch lifts and carries a check.
- [Rich text editor](https://beamline.io/components/rich-text-editor): A Notion-grade writing surface: slash menu for every block, a formatting toolbar on selection, drag-to-move blocks, nesting, markdown shortcuts, paste…
- [Allocation editor](https://beamline.io/components/allocation-editor): Parts of a fixed whole edited as transfers: an ordered strip whose boundaries drag or step between neighbours and a roster of exact amounts where typing…
- [Radio cards](https://beamline.io/components/radio-cards): One choice among rich options as cards with optional media, icon, detail and a figure; one selection ring follows the stable choice.
- [Calendar](https://beamline.io/components/calendar): Month grids for picking a day or a range: a real grid with arrows by day and week, Page keys by month, closed days, today's dot, and a range span that…
- [Availability rule editor](https://beamline.io/components/availability-rule-editor): When someone (or something) can be booked: hours for each day of the week, one or more ranges a day, a day turned off, a day's hours copied to the others…
- [Recurrence editor](https://beamline.io/components/recurrence-editor): How something repeats, set in plain controls and said back in a sentence: every N days, weeks, months or years; which weekdays; in a month, on a date or…
- [Signature pad](https://beamline.io/components/signature-pad): A pad for a drawn signature whose ink follows a stylus's pressure (and thins with speed under a mouse or finger); undo, replay, PNG or SVG export, and…
- [Image cropper](https://beamline.io/components/image-cropper): Frame a picture before it is saved: a fixed window (square, round for avatars, wide for covers, or free with handles) over the picture, which you drag…
- [Input Dissolve](https://beamline.io/components/input-dissolve): A one-line field whose text breaks into specks and drifts off once it is sent, last letter first; the field is empty and ready again.
- [Password field](https://beamline.io/components/password-field): A password field with a reveal control, and a strength meter when a password is being created.
- [Card field](https://beamline.io/components/card-field): A payment card in one field: the number groups as it is typed and names its network, the expiry and security code follow on their own as each part…
- [File drop zone](https://beamline.io/components/file-dropzone): A generous target for files: drop or choose, each checked against type, size and count with the reason when turned away; uploads show progress and can be…
- [Scrubber](https://beamline.io/components/scrubber): A budget, a timeout or a position on a scale where the neighbourhood matters: the readout says how far under or over the named limit the value is, the…
- [Slider](https://beamline.io/components/slider): A value or range on a known scale: the thumb grows under the finger and shows its value while dragged or focused; marks, end icons and a value readout.
- [Rating](https://beamline.io/components/rating): A score on a small scale: stars that fill as you point (halves too) and light one after another when chosen, with the word for the score beside them…
- [Date range picker](https://beamline.io/components/date-range-picker): A reporting range: presets on one side and two months on the other (one on a phone); the trigger names the preset in use, and the footer counts the days…
- [OTP input](https://beamline.io/components/otp-input): A verification code in separate boxes backed by one real field, so paste, SMS autofill and Backspace work; optional groups like 123–456.
- [Segmented control](https://beamline.io/components/segmented-control): Two to five views or ranges of the same content (1D / 1W / 1M, List / Board): a radio group whose raised thumb slides to the choice.
- [Stage field](https://beamline.io/components/stage-field): A record's status as its stages in order, editable in place. Stages before the current one read as passed (gone through, never "complete"); only the…
- [Layout picker](https://beamline.io/components/layout-picker): Shared record layouts for one page. Each layout says where it's used ("Used on 3 pages: Deals, this page, Forecast") and how many fields it shows, and a…
- [Tooth picker](https://beamline.io/components/tooth-picker): Teeth and their surfaces for one procedure. The arch by Universal number as you face the patient (upper 1–16, lower 32–17; supernumerary teeth on their…
- [Colour picker](https://beamline.io/components/color-picker): A swatch that opens a picker: saturation-brightness plane, hue strip, HEX/RGB/HSL/OKLCH value to type or copy, the screen eyedropper where available…
- [Emoji picker](https://beamline.io/components/emoji-picker): An emoji chosen from a search and a grid. The trigger shows the chosen emoji and opens a search above the emoji by group, with the recently used first…
- [Chip group](https://beamline.io/components/chip-group): Quick filters as chips: a chosen chip fills and grows a check, counts show what each would return, and extra chips fold behind “+N”.
- [Shortcut recorder](https://beamline.io/components/shortcut-recorder): Lets people set their own shortcut: press the keys, see them as keycaps; a clash or a browser-kept shortcut asks first. ShortcutCheatsheet lists every…
- [Mention input](https://beamline.io/components/mention-input): A composer where @people and #channels become single tokens with suggestions at the caret; the value keeps the text and where each mention sits.
- [Tag input](https://beamline.io/components/tag-input): Short free-form values as tags: Enter, comma or Tab adds, a pasted list adds them all, Backspace twice removes the last; duplicates and invalid values…
- [Multi-select](https://beamline.io/components/multi-select): Several values from a known list as removable chips in the field; the list has a search field (for long lists), checkable rows and a count with Clear…
- [Tree select](https://beamline.io/components/tree-select): A field that picks from a tree: departments and teams, categories and subcategories, folders, regions and cities; the list opens as an indented tree…
- [Combobox](https://beamline.io/components/combobox): One value from a long list found by typing (time zones, countries, customers): ranked matches with the match emphasised, keywords, optional group…
- [Phone input](https://beamline.io/components/phone-input): A phone number with its country: searchable picker with country and dialling codes, “+44…” switches the country, the number groups as typed, and the…
- [Date picker](https://beamline.io/components/date-picker): One date in a form: a field that opens the month grid under it with focus inside, picks and closes; Today and Clear below, optional clear button.
- [Time picker](https://beamline.io/components/time-picker): A time of day as hour and minute segments, typed or stepped, 12- or 24-hour; the clock opens a list of times at the step.
- [Reminder picker](https://beamline.io/components/reminder-picker): Snooze or remind, at an exact time. Two named actions on one picker: Snooze hides the item until then, Remind me keeps it in view and reminds at that…
- [Number field](https://beamline.io/components/number-field): A bounded number with − and +: arrows and Page keys step, typing is read in the locale and clamped on leaving, limits can be explained, and the label can…
- [Stock adjust](https://beamline.io/components/stock-adjust): An on-hand count changed with its reason: received, recounted, damaged, lost or returned; by an amount or to a new count; in the item's unit or in packs…
- [Inline edit](https://beamline.io/components/inline-edit): Text, a number or an amount of money that becomes a field in the same place: Enter (or ⌘Enter when multiline) saves, Escape cancels, leaving saves…
- [Search field](https://beamline.io/components/search-field): The search entry point: magnifier, clear button, Escape to clear, a shortcut hint and an optional live border beam.
- [Switch](https://beamline.io/components/switch): A setting that applies at once: a thumb that slides on a spring and stretches under the finger, with an optional label before or after.
- [Form](https://beamline.io/components/form): Validation wiring for react-hook-form (and zod) on the system's own fields: each field already links its label, help and error, so FormField hands over…
- [Select](https://beamline.io/components/select): One choice from a short known list, in the same frame as every text field: label, help, error, option groups and details.
- [Toggle group](https://beamline.io/components/toggle-group): Pressable toggles where one or several can be on: alignment, bold and italic, view options; bare for toolbars or framed.
- [Input](https://beamline.io/components/input): A single-line text field with its label, help and error wired for assistive tech, three sizes and adornments. With complete or emailDomains it offers…
- [Checkbox](https://beamline.io/components/checkbox): A yes/no choice with an optional label and help, including the mixed state for select-all; the check draws itself in.
- [Radio group](https://beamline.io/components/radio-group): One choice from a short visible set, each option with an optional description, vertical or in a row.
- [Textarea](https://beamline.io/components/textarea): Multi-line plain text that grows with what is typed up to a limit, with an optional character count.
- [Label](https://beamline.io/components/label): The text label tied to a form control, with a required marker that screen readers announce.
- [Count adjust](https://beamline.io/components/count-adjust): A count of whole things against its whole (received of ordered, credits of bought), set by hand: what is on record stays solid, the change is drawn as…

Part of [Beamline UI: polished, editable React components and complete screens for custom applications](https://beamline.io/). [Build your own style from any look; tokens, fonts, radii, motion; not only colours](https://beamline.io/docs/customize).
