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
| Option | Type | Default | Description |
|---|
| initialX | number | window.innerWidth - 390 | Initial horizontal position |
| initialY | number | 64 | Initial vertical position |
| minVisibleHorizontal | number | 390 | Minimum pixels visible horizontally when near edge |
| minVisibleVertical | number | 56 | Minimum pixels visible vertically when near edge |
| width | number | 390 | Width of the draggable element |
Returns
| Property | Type | Description |
|---|
| position | { x: number; y: number } | Current position coordinates |
| isDragging | boolean | Whether the element is currently being dragged |
| handleMouseDown | (e: MouseEvent) => void | Handler to attach to the drag trigger element |
| resetPosition | () => void | Resets 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