Skip to main content

PointsEditor

Editor for a set of points, each one dragged within the same area.

A point is placed by its position in the container, so its value is { x, y } in the range 0..1 on each axis, with y growing downwards. Points can be selected and moved together, with ctrl / meta or by dragging a <PointsEditor.SelectionBox /> over them.

Source Style

Drag a point, or click one and use the arrow keys. The wheel moves the focused point from anywhere over the editor, and shift switches it to the x axis.

Loading...
function App() {
  const [points, setPoints] = useState({
    'p-0': { x: 0, y: 0.5 },
    'p-1': { x: 0.35, y: 0.15 },
    'p-2': { x: 0.7, y: 0.85 },
    'p-3': { x: 1, y: 0.5 },
  })

  return (
    <div>
      <PointsEditor.Root className={pointsEditorTheme.root} selectable>
        <PointsEditor.Background
          style={{ background: '#f2f4f5', borderRadius: 4 }}
        />
        <PointsEditor.Container>
          {Object.entries(points).map(([id, point]) => (
            <PointsEditor.Point
              className={pointsEditorTheme.point}
              key={id}
              id={id}
              value={point}
              onChange={(value) =>
                setPoints((prev) => ({ ...prev, [id]: value }))
              }
            />
          ))}
          <PointsEditor.SelectionBox
            className={pointsEditorTheme.selectionBox}
          />
        </PointsEditor.Container>
      </PointsEditor.Root>
      <p>
        {Object.entries(points)
          .map(([id, { x, y }]) => `${id}: (${x}, ${y})`)
          .join(' / ')}
      </p>
    </div>
  )
}

Import​

import { PointsEditor } from '@tremolo-ui/react'

API Reference​

Each part lists the props of its own. It also takes the attributes of the element it renders, such as className and style.

In Svelte and Vue the props are the same, written their way — class rather than className, bind:value or v-model, snippets or slots for content. See Svelte and Vue.

State is on the element as a data attribute, so it is a selector away — see Styling. An attribute is only there while its state is on.

Root​

Holds the selection and the settings every point shares.

PropTypeDefault
disabledboolean—
readOnlyboolean—
dragCursorCursor'grabbing'
wheelModifierValue<InputEventOption> | null['normalized', 0.01]
keyboardModifierValue<InputEventOption> | null{ default: ['normalized', 0.01], shift: ['normalized', 0.001] }
dragSensitivityModifierValue<number>{ default: 1, shift: 0.1 }
selectablebooleanfalse
selectionstring[]—
defaultSelectionstring[]—
onSelectionChange(selection: string[]) => void—
children*ReactNode—

Full reference: PointsEditorProps

Set the editor's width and height with CSS or style.

Data attributeValues
[data-disabled]Present when disabled is set
[data-readonly]Present when readonly is set

Background​

Drawn behind the points. Whatever they are placed over goes inside it: a graph, a canvas, an image.

It has no props of its own and takes the attributes of a <div>.

Container​

The area the points are placed in. A drag on its empty space draws a selection. PointsEditor.Point goes inside it.

It has no props of its own and takes the attributes of a <div>.

Point​

One point, moved by dragging, the arrow keys or the wheel. Two visually hidden range inputs inside it, one per axis, take the focus and carry the ARIA. Children are drawn inside the point; the theme's own dot stands when there are none.

PropTypeDefault
value*T—
idstring—
minPartial<PointPosition>—
maxPartial<PointPosition>—
colorstring—
disabledboolean—
readOnlyboolean—
wheelModifierValue<InputEventOption> | null—
keyboardModifierValue<InputEventOption> | null—
aria-labelstring | Partial<Record<"x" | "y", string>>—
aria-valuetextstring | Partial<Record<"x" | "y", string>>—
onChange(value: PointPosition) => void—
onChangeStart(value: PointPosition, source: ChangeSource) => void—
onChangeEnd(value: PointPosition, source: ChangeSource) => void—
changeEndDelaynumber500

Full reference: PointsEditorPointProps

Custom propertyWritten byWhat it sets
--colorcolorColour of the point.

Set a point's width and height with CSS or style.

Data attributeValues
[data-disabled]Present when disabled is set, on the point or on Root
[data-readonly]Present when readonly is set, on the point or on Root
[data-dragging]Present while the point is being dragged
[data-selected]Present while the point is in the selection

SelectionBox​

The box a drag on empty space draws; the points it covers are selected. Nothing is rendered while no drag is running, children included.

It has no props of its own and takes the attributes of a <div>.