cnc-drag-block
A block on a continuous axis: drag the body to move it with its duration intact, or drag either
handle to resize that edge. Every gesture snaps to step, clamps to
[min, max], and holds a min-size. It is the geometry primitive under
timeblocking and the calendar day column, and it is unit-agnostic — minutes from midnight,
epoch milliseconds, or plain numbers.
Quick start
Declare the scale — the range, the step, and how many pixels one unit is worth —
then bind $start and $end. The widget positions itself absolutely
inside the nearest positioned ancestor, so give it a container with a height (on
y) or a width (on x).
<!-- a 09:00-17:00 window: minutes 540-1020, quarter-hour steps, 0.8px per minute -->
<div class="relative" style="height: 384px">
<cnc-drag-block
axis="y" min="540" max="1020" step="15" min-size="30" px-per-unit="0.8"
start="600" end="720" label="appointment"
$start="s" $end="e"
></cnc-drag-block>
</div>
Arrow keys nudge by one step, ×4 with Shift. Tab to the body to move it, or to either handle to resize that edge — a continuous control has to be operable without a pointer.
Usage guidance
This widget owns move, resize, snap and clamp — and nothing else. Overlap layout, DST, recurrence, virtualisation and what a move actually means are the consumer's, which is what keeps it usable for a calendar column, a Gantt row and a range on a chart alike.
Choose units that make step a whole number — minutes from midnight rather
than fractional hours — and let
px-per-unit
carry the zoom. For a single value rather than a band, use
cnc-slider; for a whole day of blocks with collision handling, use the calendar
widgets built on this one.