Documentation
API: primitives (@fragiola/dockable-react)

Dockable.DropIndicator

The drop outline of a drag, one element positioned over the drop target and hidden when there is none.

"The drop outline of a drag: one element, positioned (structurally) over the rect the core computed, hidden when there is no drop target. Place it anywhere inside Dockable.Root. It has no content of its own."

<Dockable.DropIndicator
    className="z-10 rounded-md border-2 border-palette-ring bg-palette-ring/15 data-[drop-kind=edge]:border-dashed"
    style={(state) => ({ transition: `all ${state.tabDragSpeed}s` })}
/>

Give it a z-index: the panels are portalled into the root after it and would paint over it (gap 12).

Props

DropIndicatorProps extends the common primitive props.

proptypedefaultdescription
childrenReactNodenoneoptional content (an icon, a hint)

State

DropIndicatorState:

fieldtypedescription
visiblebooleana drop target is under the pointer
location"center" | "top" | "bottom" | "start" | "end"where the dragged node would dock relative to the target
kind"rect" | "edge""edge" for a drop at the outer edge of a row, "rect" otherwise
draggingbooleana drag is over the layout
showEdgesbooleanedge docking is available for this drag
tabDragSpeednumberseconds a style may take to animate between targets
refusedbooleanthe pointer is over a target that a drop rule (or a middleware veto) refused (the outline is hidden)
targetNodeIdstring | undefinedthe id of the drop target node: a tabset, a row for an edge drop, a border
targetTabsetIdstring | undefinedthe id of the tabset (or border) the drop goes into or beside

The target ids let the outline follow the tabset it targets, for instance its palette: className={(state) => paletteOf(state.targetTabsetId)}.

Data attributes and ARIA

attributevalue
data-layout-path"/outline"
data-visiblea drop target is under the pointer
data-drop-locationwhile visible: the location
data-drop-kindwhile visible: "rect" or "edge"
data-dragginga drag is over the layout
data-drop-refusedthe pointer is over a target that a drop rule refused
aria-hiddentrue

Structural style

position: absolute, left, top, width, height (the target rect, relative to the root), display: none while not visible, and pointer-events: none: "hit-testing, not cosmetics: an indicator under the pointer would take the drag's enter/leave events from the layout and make the browser cancel the drop."

Notes

  • The target is the first candidate under the pointer whose command the model accepts: the engine turns each candidate into the command the drop would run (tab.move, tabset.move, or tab.add for a new tab) and asks model.can. A middleware that vetoes the command refuses the drop, and the drop itself runs it through model.run. See Restricting drops.

  • One indicator per layout: inside Dockable.Popout, render another one for the window if drops inside popouts should show an outline.

  • The core never animates. tabDragSpeed (from Root, default 0.3) is a duration hint for your transition.