Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modular neodrag #180

Open
PuruVJ opened this issue Dec 9, 2024 · 0 comments
Open

modular neodrag #180

PuruVJ opened this issue Dec 9, 2024 · 0 comments

Comments

@PuruVJ
Copy link
Owner

PuruVJ commented Dec 9, 2024

Thinking of this API:

import { draggable } from 'neodrag/svelte'

draggable({
  transform?: (data) => string | void
  applyUserSelectHack?: boolean
  disabled?: boolean
  threshold?: {delay?:number, distance?: number}
  onDragStart, onDrag, onDragEnd
})

This will be the base API.

And the candidates for plugins:

  • bounds(recomputeBounds)
  • classes
  • handle Merge handle cancel under one controls plugin
  • cancel
  • position
  • ignoreMultitouch
  • axis

Possibly position also has to be in the base properties, being a fundamental property.

Usage:

draggable({
  plugins: [bounds({recomputeBounds: {}, from: [], to}), handle('.handle'), cancel('.cancel')]
})

Another main question is to make sure the plugin functions execute once and only once. If user has disabled: disabledState, this will cause entire object to be recreated, hence resetting the plugin functions and their states also. Maybe can be solved with privateState that is stored in neodrag itself. But seems hacky. We should make sure these functions are not recreated, or if it is unavoidable, they are idempotent enough

Plugin API

Rough sketch of how it looks.

type State = {
  // Raw movement from pointer event (read-only)
  readonly dx: number;
  readonly dy: number;
  
  // Current position (mutable)
  x: number;
  y: number;
  
  // Drag status
  isDragging: boolean;
  
  // Element reference
  element: HTMLElement;
  
  // Starting point
  initial: { x: number; y: number };
}

type Plugin = {
  // Identifier for the plugin
  name: string;

  // When plugin runs:
  // 'pre' - early, for modifying input (like grid, axis)
  // 'post' - late, for applying constraints (like bounds)
  phase: 'pre' | 'post';

  // Called when plugin is initialized
  setup?: (context: { 
    element: HTMLElement;
    state: State;
  }) => void;

  // Start of drag - return false to prevent drag
  dragStart?: (state: State, event: PointerEvent) => 
    Partial<State> | false | void;

  // During drag - return state modifications
  drag?: (state: State, event: PointerEvent) => 
    Partial<State> | void;

  // End of drag
  dragEnd?: (state: State, event: PointerEvent) => 
    Partial<State> | void;

  // Cleanup when draggable is destroyed
  cleanup?: () => void;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant