Skip to content

useHeroSlider

The core composable that manages all slider state — navigation, autoplay, video, and hover detection.

Usage

ts
const containerRef = useTemplateRef('containerRef')
const slides = ref<HeroSlide[]>([...])

const slider = useHeroSlider(containerRef, slides, {
  swiperOptions: { autoplay: { delay: 5000 }, speed: 600, effect: 'fade' },
  showPagination: true,
  showNavigation: true,
  showProgress: true,
  watchMode: false,
})

Parameters

ParameterTypeDescription
containerRefMaybeRefOrGetter<HTMLElement | null>Root DOM element or component ref — used for hover detection and GSAP scoping
slidesMaybeRefOrGetter<HeroSlide[]>Reactive array of slide definitions
optionsUseHeroSliderOptionsConfiguration object (see below)

Options

ts
interface UseHeroSliderOptions {
  swiperOptions?: SwiperOptions
  enterAnimation?: string        // Default: ''
  leaveAnimation?: string        // Default: ''
  showPagination?: boolean       // Default: true
  showNavigation?: boolean       // Default: true
  showProgress?: boolean         // Default: true
  showVideoControls?: boolean    // Default: true
  watchMode?: boolean            // Default: false
  watchIdleMs?: number           // Default: 10000
}

Swiper Options

All standard Swiper options are accepted via swiperOptions:

ts
useHeroSlider(container, slides, {
  swiperOptions: {
    effect: 'fade',              // 'fade' | 'cube' | 'coverflow' | 'creative' | 'cards' | 'flip'
    direction: 'vertical',      // 'horizontal' | 'vertical'
    speed: 800,                  // Transition speed in ms
    loop: true,                  // Infinite loop
    slidesPerView: 1,            // Visible slides
    spaceBetween: 0,             // Gap between slides (px)
    centeredSlides: false,       // Center active slide
    grabCursor: true,            // Show grab cursor
    mousewheel: true,            // Mousewheel control (auto-registers module)
    autoplay: { delay: 5000 },   // Autoplay delay (timer is managed internally)
    breakpoints: {               // Responsive breakpoints
      768: { slidesPerView: 2 },
      1024: { slidesPerView: 3 },
    },
  },
})

TIP

Swiper's native autoplay is always disabled. The composable manages its own progress timer using autoplay.delay as the interval. This enables smooth progress tracking and video-aware pausing.

WARNING

effect: 'cube' is designed for exactly 4 slides. Using a different count triggers a dev-time warning. Use 'cards' or 'coverflow' for other counts.

Watch Mode

Watch mode provides a cinema-like experience for video slides. When active and the video is playing, content, overlay patterns, and the play button fade out. After watchIdleMs of mouse inactivity, video controls slide out too.

ts
useHeroSlider(container, slides, {
  watchMode: true,        // Enable globally
  watchIdleMs: 8000,      // 8 seconds idle before hiding controls
})

Per-slide override:

ts
const slides = [
  {
    bgSrc: '/cinematic.mp4',
    config: {
      watchMode: true,      // Enable for this slide only
      watchIdleMs: 5000,    // Custom idle timeout
    },
  },
]

Return Value

The composable returns a flat object with all slider state and controls:

PropertyTypeDescription
next()() => voidGo to next slide
prev()() => voidGo to previous slide
goTo(index)(index: number) => voidGo to specific slide

Slide State

PropertyTypeDescription
activeIndexRef<number>Current active slide index
snapIndexRef<number>Current snap point index
totalSnapsRef<number>Total snap points
activeSlideComputedRef<HeroSlide>Current slide data
activeSlideConfigComputedRef<ResolvedSlideConfig>Resolved config with defaults
isActiveSlideVideoComputedRef<boolean>Whether active slide has video bg
isMultiSlideComputedRef<boolean>True when slidesPerView > 1 — disables content animations
animationClass(index)(index: number) => stringGet CSS animation class for a slide

Autoplay

PropertyTypeDescription
autoplayEnabledbooleanWhether autoplay is configured
autoplayProgressComputedRef<number>Progress 0–1 of current timer
autoplayRemainingComputedRef<number>Remaining ms before advance
autoplayDelayRef<number>Current delay in ms
autoplayPausedRef<boolean>Whether autoplay is paused
autoplayPause()() => voidPause the timer
autoplayResume()() => voidResume the timer
autoplayReset()() => voidReset the timer
autoplaySetDelay(ms)(ms: number) => voidChange autoplay delay

Video

PropertyTypeDescription
videoPlayingComputedRef<boolean>Video playback state
videoCurrentTimeComputedRef<number>Current position (seconds)
videoDurationComputedRef<number>Total duration (seconds)
videoBufferedComputedRef<number>Buffered amount
videoVolumeComputedRef<number>Volume (0–1)
videoMutedComputedRef<boolean>Mute state
videoWaitingComputedRef<boolean>Buffering state
videoEndedComputedRef<boolean>Video has ended
videoToggle()() => voidPlay/pause toggle
videoSeek(time)(time: number) => voidSeek to position
videoScrubStart()() => voidCall when scrubber drag starts
videoScrubEnd()() => voidCall when scrubber drag ends
videoSetVolume(v)(v: number) => voidSet volume
videoToggleMute()() => voidToggle mute

Other

PropertyTypeDescription
isHoveredRef<boolean>Whether the container is being hovered
containerElComputedRef<HTMLElement | null>Resolved container DOM element
mergedSwiperOptionsComputedRef<Record<string, unknown>>Final Swiper config (for component binding)

Released under the MIT License.