axis

axis

Restrict movement to a single axis (x or y)

The axis plugin locks movement to horizontal (x) or vertical (y) direction. Perfect for sliders, scrollbars, or any UI requiring one-dimensional dragging.

axis('x'); // Only horizontal movement
axis('y'); // Only vertical movement
axis(null); // Free movement (removes constraint)

Basic Usage

<script>
  import { axis } from '@neodrag/svelte';
</script>

<!-- Horizontal slider -->
<div {@attach draggable([axis('x')])}>Horizontal only</div>

<!-- Vertical scrollbar -->
<div {@attach draggable([axis('y')])}>Vertical only</div>

<!-- Free movement -->
<div {@attach draggable([axis(null)])}>Any direction</div>

Dynamic Axis Switching

<script>
  import { draggable, axis, Compartment } from '@neodrag/svelte';

  let currentAxis = $state('x');
  const axisComp = Compartment.of(() => axis(currentAxis));
</script>

<div {@attach draggable(() => [axisComp])}>
  Currently locked to: {currentAxis} axis
</div>

<button
  onclick={() => (currentAxis = currentAxis === 'x' ? 'y' : 'x')}
>
  Switch to {currentAxis === 'x' ? 'Y' : 'X'} axis
</button>

Real-World Examples

Horizontal Slider Component

<script>
  import {
    draggable,
    axis,
    bounds,
    BoundsFrom,
    events,
  } from '@neodrag/svelte';

  let track;
  let handle;
  let value = $state(50);

  function handleDrag(data) {
    if (track) {
      const trackWidth = track.offsetWidth;
      value = Math.round((data.offset.x / trackWidth) * 100);
    }
  }
</script>

<div bind:this={track} class="track">
  <div
    bind:this={handle}
    class="handle"
    {@attach draggable([
      axis('x'),
      bounds(() => BoundsFrom.element(track)),
      events({ onDrag: handleDrag }),
    ])}
  />
</div>
<p>Value: {value}%</p>

Split Pane Resizer

// Vertical divider for horizontal split
const plugins = [
  axis('x'),
  bounds(
    BoundsFrom.parent({
      left: 100, // Min pane width
      right: 100, // Min pane width
    }),
  ),
];

How It Works

The axis plugin modifies the proposed movement during dragging:

  • axis('x'): Sets proposed.y = null (no vertical movement)
  • axis('y'): Sets proposed.x = null (no horizontal movement)
  • axis(null): No changes (free movement)

This happens in the plugin’s drag hook, so other plugins receive the constrained movement values.

API Reference

function axis(value?: 'x' | 'y' | null | undefined): Plugin;

Parameters:

  • value - The axis to constrain movement to
    • 'x' - Horizontal only
    • 'y' - Vertical only
    • null or undefined - No constraint

Returns: A plugin object for use with draggable.