Skip to main content
A hook for making the chat window draggable within the viewport.

Usage

import { ChatWindow, Header, useDraggable } from "@servicetitan/ext-atlas";

function DraggableChatWindow() {
  const {
    position,
    isDragging,
    handleMouseDown,
    resetPosition,
  } = useDraggable({
    initialX: window.innerWidth - 390,
    initialY: 64,
    width: 390,
  });

  return (
    <ChatWindow open position={position} isDragging={isDragging}>
      <Header
        title="Atlas"
        isDraggable
        isDragging={isDragging}
        onMouseDown={handleMouseDown}
      />
      {/* Content */}
    </ChatWindow>
  );
}

Options

OptionTypeDefaultDescription
initialXnumberwindow.innerWidth - 390Initial horizontal position
initialYnumber64Initial vertical position
minVisibleHorizontalnumber390Minimum pixels visible horizontally when near edge
minVisibleVerticalnumber56Minimum pixels visible vertically when near edge
widthnumber390Width of the draggable element

Returns

PropertyTypeDescription
position{ x: number; y: number }Current position coordinates
isDraggingbooleanWhether the element is currently being dragged
handleMouseDown(e: MouseEvent) => voidHandler to attach to the drag trigger element
resetPosition() => voidResets position to calculated initial position

Behavior

  • Viewport Constraints: Position is constrained to keep the minimum visible pixels within the viewport
  • Resize Handling: Automatically adjusts position when window is resized
  • Text Selection: Prevents text selection while dragging
  • Mouse Events: Attaches global mouse events during drag for smooth tracking

Example: Reset on Fullscreen Exit

function ChatWithReset() {
  const [fullscreen, setFullscreen] = useState(false);
  const { position, isDragging, handleMouseDown, resetPosition } = useDraggable();

  const handleFullscreenToggle = () => {
    if (fullscreen) {
      resetPosition(); // Reset to default position when exiting fullscreen
    }
    setFullscreen(!fullscreen);
  };

  return (
    <ChatWindow
      open
      fullscreen={fullscreen}
      position={fullscreen ? undefined : position}
      isDragging={isDragging}
    >
      <Header
        isDraggable={!fullscreen}
        isDragging={isDragging}
        onMouseDown={handleMouseDown}
        onFullscreen={handleFullscreenToggle}
        isExpanded={fullscreen}
      />
    </ChatWindow>
  );
}
Last modified on February 3, 2026