Skip to content
Docs
Motion

인터랙션 훅

stable

호버, 클릭, 포커스, 키보드 이벤트에 반응하는 인터랙션 모션 훅

Import

import {
  useHoverMotion,
  useClickToggle,
  useFocusToggle,
  useButtonEffect,
  useInteractive,
  useKeyboardToggle,
} from '@hua-labs/motion-core'

useHoverMotion

마우스 호버 시 스케일, 이동, 투명도 변화를 애니메이션한다.

Signature

function useHoverMotion<T extends MotionElement = HTMLDivElement>(
  options?: HoverMotionOptions
): BaseMotionReturn<T> & { isHovered: boolean }

Parameters

파라미터타입기본값설명
hoverScalenumber프로필 기본값호버 시 스케일
hoverYnumber프로필 기본값호버 시 Y 오프셋 (px)
hoverOpacitynumber1호버 시 투명도
durationnumber프로필 기본값전환 지속 시간 (ms)
easingstring프로필 기본값CSS 이징

Returns

이름타입설명
refRefObject<T>DOM 요소 참조
styleMotionStyle적용할 CSS 스타일
isHoveredboolean현재 호버 여부
isAnimatingboolean애니메이션 진행 여부

Usage

import { useHoverMotion } from '@hua-labs/motion-core'

function HoverCard() {
  const { ref, style, isHovered } = useHoverMotion({
    hoverScale: 1.05,
    hoverY: -4,
    duration: 200
  })

  return (
    <div ref={ref} style={style}>
      {isHovered ? '호버 중' : '호버해 보세요'}
    </div>
  )
}

useClickToggle

클릭, 더블클릭, 우클릭, Enter/Space 키로 활성 상태를 토글한다.

Signature

function useClickToggle(options?: ClickToggleOptions): ClickToggleReturn

interface ClickToggleReturn {
  isActive: boolean
  mounted: boolean
  toggle: () => void
  activate: () => void
  deactivate: () => void
  reset: () => void
  clickHandlers: {
    onClick?: (event: React.MouseEvent) => void
    onDoubleClick?: (event: React.MouseEvent) => void
    onContextMenu?: (event: React.MouseEvent) => void
    onKeyDown?: (event: React.KeyboardEvent) => void
  }
}

Parameters

파라미터타입기본값설명
initialStatebooleanfalse초기 상태
toggleOnClickbooleantrue클릭 시 토글
toggleOnDoubleClickbooleanfalse더블클릭 시 토글
toggleOnRightClickbooleanfalse우클릭 시 토글
toggleOnEnterbooleantrueEnter 키로 토글
toggleOnSpacebooleantrueSpace 키로 토글
autoResetbooleanfalse자동 리셋 여부
resetDelaynumber3000자동 리셋 지연 (ms)
preventDefaultbooleanfalse기본 이벤트 방지
stopPropagationbooleanfalse이벤트 전파 중단

Usage

import { useClickToggle } from '@hua-labs/motion-core'

function ToggleButton() {
  const { isActive, clickHandlers, mounted } = useClickToggle({
    toggleOnClick: true,
    autoReset: true,
    resetDelay: 2000
  })

  if (!mounted) return null

  return (
    <button
      {...clickHandlers}
      style={{ opacity: isActive ? 1 : 0.6 }}
    >
      {isActive ? '활성' : '비활성'}
    </button>
  )
}

useFocusToggle

포커스/블러 이벤트로 활성 상태를 토글한다.

Signature

function useFocusToggle(options?: FocusToggleOptions): FocusToggleReturn

interface FocusToggleReturn {
  isActive: boolean
  mounted: boolean
  toggle: () => void
  activate: () => void
  deactivate: () => void
  reset: () => void
  focusHandlers: {
    onFocus?: (event: React.FocusEvent) => void
    onBlur?: (event: React.FocusEvent) => void
    onFocusIn?: (event: React.FocusEvent) => void
    onFocusOut?: (event: React.FocusEvent) => void
  }
  ref: RefObject<HTMLElement | null>
}

Parameters

파라미터타입기본값설명
initialStatebooleanfalse초기 상태
toggleOnFocusbooleantrue포커스 시 활성화
toggleOnBlurbooleanfalse블러 시 비활성화
autoResetbooleanfalse자동 리셋
resetDelaynumber3000자동 리셋 지연 (ms)

Usage

import { useFocusToggle } from '@hua-labs/motion-core'

function FocusInput() {
  const { isActive, focusHandlers } = useFocusToggle({
    toggleOnFocus: true,
    toggleOnBlur: true
  })

  return (
    <input
      {...focusHandlers}
      style={{
        outline: isActive ? '2px solid blue' : 'none',
        transition: 'outline 150ms ease'
      }}
    />
  )
}

useButtonEffect

버튼에 scale, ripple, glow, shake, bounce, slide 등 다양한 시각 효과를 적용한다.

Signature

function useButtonEffect<T extends MotionElement = HTMLButtonElement>(
  options?: ButtonEffectOptions
): BaseMotionReturn<T> & {
  buttonType: string
  isPressed: boolean
  isHovered: boolean
  isFocused: boolean
  ripplePosition: { x: number; y: number }
  currentGlowIntensity: number
  shakeOffset: number
  bounceOffset: number
  slideOffset: number
  pressButton: () => void
  releaseButton: () => void
  setButtonState: (state: 'idle' | 'hover' | 'active' | 'focus' | 'disabled') => void
}

Parameters (주요)

파라미터타입기본값설명
type`'scale' \'ripple' \'glow' \'shake' \'bounce' \'slide'`'scale'효과 타입
hoverScalenumber1.05호버 스케일
activeScalenumber0.95클릭 스케일
durationnumber200전환 시간 (ms)
disabledbooleanfalse비활성화
disabledOpacitynumber0.5비활성화 시 투명도

Usage

import { useButtonEffect } from '@hua-labs/motion-core'

function AnimatedButton() {
  const { ref, style, pressButton, releaseButton } = useButtonEffect({
    type: 'scale',
    hoverScale: 1.08,
    activeScale: 0.92
  })

  return (
    <button
      ref={ref}
      style={style}
      onMouseDown={pressButton}
      onMouseUp={releaseButton}
    >
      클릭해 보세요
    </button>
  )
}

useInteractive

호버/클릭 상태에 따른 스케일 변화를 간단하게 관리하는 내부 유틸리티 훅이다.

Signature

function useInteractive(config?: InteractiveConfig): {
  ref: (element: HTMLDivElement | null) => void
  scale: number
  isHovered: boolean
  isClicked: boolean
  handleMouseEnter: () => void
  handleMouseLeave: () => void
  handleMouseDown: () => void
  handleMouseUp: () => void
}

interface InteractiveConfig {
  hoverScale?: number   // 기본값: 1.05
  clickScale?: number   // 기본값: 0.95
  duration?: number     // 기본값: 200
}

Usage

import { useInteractive } from '@hua-labs/motion-core'

function InteractiveCard() {
  const {
    ref,
    scale,
    handleMouseEnter,
    handleMouseLeave,
    handleMouseDown,
    handleMouseUp
  } = useInteractive({ hoverScale: 1.03, clickScale: 0.98 })

  return (
    <div
      ref={ref}
      style={{ transform: `scale(${scale})`, transition: 'transform 200ms ease' }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      onMouseDown={handleMouseDown}
      onMouseUp={handleMouseUp}
    >
      카드
    </div>
  )
}

useKeyboardToggle

키보드 입력으로 활성 상태를 토글한다. 키 조합(key combo)과 전역 리스너를 지원한다.

Signature

function useKeyboardToggle(options?: KeyboardToggleConfig): KeyboardToggleReturn

interface KeyboardToggleReturn {
  isActive: boolean
  mounted: boolean
  toggle: () => void
  activate: () => void
  deactivate: () => void
  reset: () => void
  keyboardHandlers: {
    onKeyDown?: (event: React.KeyboardEvent) => void
    onKeyUp?: (event: React.KeyboardEvent) => void
    onKeyPress?: (event: React.KeyboardEvent) => void
  }
  ref: RefObject<HTMLElement | null>
}

Parameters

파라미터타입기본값설명
keysstring[][' ']토글할 키 목록
keyCombostring[]키 조합 (예: ['Control', 'K'])
toggleOnKeyDownbooleantrue키다운 시 토글
toggleOnKeyUpbooleanfalse키업 시 토글
requireFocusbooleanfalse포커스된 요소에서만 동작
autoResetbooleanfalse자동 리셋
resetDelaynumber3000자동 리셋 지연 (ms)

Usage

import { useKeyboardToggle } from '@hua-labs/motion-core'

function SearchModal() {
  // Ctrl+K로 토글
  const { isActive } = useKeyboardToggle({
    keyCombo: ['Control', 'k'],
    preventDefault: true
  })

  return isActive ? <div>검색 모달</div> : null
}

Notes

  • useClickToggle, useFocusToggle, useKeyboardToggle은 모두 mounted 상태를 반환하므로 SSR 하이드레이션 이슈에 주의한다.
  • useButtonEffectripple 타입은 createRipple 함수를 마우스 이벤트에 직접 연결해야 한다.
  • useInteractive@internal 태그가 붙어 있으며 패키지 내부 용도로 설계됐다.