useFloatingWindow

useFloatingWindow (드래그 가능한 부유 창)

useFloatingWindow 훅은 주어진 요소를 드래그할 수 있게 만들어요. 뷰포트 제약, 드래그 핸들, 축 잠금 등 다양한 옵션을 제공해요.

출처: 문서

본문

useFloatingWindow 훅은 주어진 요소를 드래그할 수 있게 만들어요.

import { Button, CloseButton, Group, Paper, Portal, Text } from '@mantine/core';
import { useDisclosure, useFloatingWindow } from '@mantine/hooks';

function Demo() {
  const [visible, handlers] = useDisclosure();
  const floatingWindow = useFloatingWindow({
    constrainToViewport: true,
    constrainOffset: 20,
    excludeDragHandleSelector: 'button',
    initialPosition: { top: 300, left: 20 },
  });

  return (
    <>
      <Button onClick={handlers.toggle}>
        {visible ? 'Hide' : 'Show'} floating window
      </Button>
      {visible && (
        <Portal>
          <Paper ref={floatingWindow.ref} shadow="md" p="xl" pos="fixed" w={300}>
            <Group justify="space-between" mb="xs">
              <Text fw={500}>Usage demo</Text>
              <CloseButton onClick={handlers.close} />
            </Group>
            <Text size="sm">This is a floating window. You can drag it around.</Text>
          </Paper>
        </Portal>
      )}
    </>
  );
}

뷰포트 제약 (Constrain to viewport)

constrainToViewport 옵션으로 요소의 이동을 뷰포트 경계 안으로 제한할 수 있어요. 이 옵션을 설정하지 않으면 요소를 뷰포트 밖으로 드래그할 수 있어요.

제약 오프셋 (Constrain offset)

constrainOffset 옵션으로 요소를 제약할 때 뷰포트 가장자리로부터의 오프셋을 설정해요. 이 옵션은 constrainToViewport: true가 필요해요.

드래그 핸들 셀렉터 (Drag handle selector)

dragHandleSelector 옵션으로 부유 창을 드래그하는 데 사용할 요소(또는 요소 그룹)의 셀렉터를 지정할 수 있어요. 지정하지 않으면 전체 루트 요소가 드래그 대상이 돼요.

excludeDragHandleSelector 옵션은 dragHandleSelector 내부의 요소를 드래그 이벤트에서 제외해요.

Enabled 옵션

enabled 옵션으로 드래그를 활성화/비활성화할 수 있어요.

위치 설정 (Set position)

setPosition 함수를 호출해 요소의 위치를 프로그래밍 방식으로 설정할 수 있어요. 이 함수는 top, left, right, bottom 속성을 가진 객체를 받으며, 그중 두 가지만 지정하면 돼요(예: top과 left, 또는 bottom과 right).

floatingWindow.setPosition({ bottom: 40, right: 40 });

축 잠금 (Lock axis)

axis 옵션으로 이동을 지정한 축으로 제한할 수 있어요.

FloatingWindow 컴포넌트

컴포넌트 API를 선호한다면 FloatingWindow 컴포넌트를 사용할 수 있어요. 이 컴포넌트는 훅과 동일한 옵션을 지원하며 포털 렌더링, 기본 스타일 등의 추가 기능을 제공해요.

정의 (Definition)

function useFloatingWindow(
  options?: UseFloatingWindowOptions
): UseFloatingWindowReturnValue

interface FloatingWindowPositionConfig {
  top?: number;
  left?: number;
  right?: number;
  bottom?: number;
}

interface FloatingWindowPosition {
  /** Element offset from the left side of the viewport */
  x: number;
  /** Element offset from the top side of the viewport */
  y: number;
}

interface UseFloatingWindowOptions {
  /** If `false`, the element can not be dragged. */
  enabled?: boolean;
  /** If `true`, the element can only move within
   * the current viewport boundaries. */
  constrainToViewport?: boolean;
  /** The offset from the viewport edges when constraining the element.
   * Requires `constrainToViewport: true`. */
  constrainOffset?: number;
  /** Selector of an element that should be used to drag floating window.
   * If not specified, the entire root element is used as a drag target. */
  dragHandleSelector?: string;
  /** Selector of an element within `dragHandleSelector`
   * that should be excluded from the drag event. */
  excludeDragHandleSelector?: string;
  /** If set, restricts movement to the specified axis */
  axis?: 'x' | 'y';
  /** Initial position. If not set, calculated from element styles. */
  initialPosition?: FloatingWindowPositionConfig;
  /** Called when the element position changes */
  onPositionChange?: (pos: FloatingWindowPosition) => void;
  /** Called when the drag starts */
  onDragStart?: () => void;
  /** Called when the drag stops */
  onDragEnd?: () => void;
}

type SetFloatingWindowPosition = (position: FloatingWindowPositionConfig) => void;

interface UseFloatingWindowReturnValue {
  /** Ref to the element that should be draggable */
  ref: RefCallback;
  /** Function to set the position of the element */
  setPosition: SetFloatingWindowPosition;
  /** `true` if the element is currently being dragged */
  isDragging: boolean;
}

Exported types

UseFloatingWindowOptions와 UseFloatingWindowReturnValue 타입은 @mantine/hooks 패키지에서 내보내져요.

import type { UseFloatingWindowOptions, UseFloatingWindowReturnValue } from '@mantine/hooks';

더 알아보기 (Learn more)