Skip to content

v-resize

Observe element resize using ResizeObserver.

Since: 1.1.0

Usage

Basic

vue
<template>
  <div v-resize="handleResize">Resize me</div>
</template>

<script setup>
function handleResize(entry) {
  console.log('New size:', entry.contentRect.width, entry.contentRect.height)
}
</script>

With Options

vue
<template>
  <div v-resize="{
    handler: handleResize,
    debounce: 200,
    box: 'border-box'
  }">
    Debounced resize
  </div>
</template>

API

Types

typescript
interface ResizeInfo {
  /** New width */
  width: number
  /** New height */
  height: number
  /** Content rect */
  contentRect: DOMRectReadOnly
  /** Border box size */
  borderBoxSize: ReadonlyArray<ResizeObserverSize>
  /** Content box size */
  contentBoxSize: ReadonlyArray<ResizeObserverSize>
  /** Device pixel content box size */
  devicePixelContentBoxSize: ReadonlyArray<ResizeObserverSize>
}

type ResizeHandler = (entry: ResizeObserverEntry) => void

interface ResizeOptions {
  /** Resize event handler */
  handler: ResizeHandler
  /** Disable the directive */
  disabled?: boolean
  /** Box model to observe */
  box?: 'content-box' | 'border-box' | 'device-pixel-content-box'
  /** Debounce time in milliseconds */
  debounce?: number
  /** Callback for browsers without ResizeObserver */
  onFallback?: (info: ResizeInfo) => void
}

type ResizeBinding = ResizeHandler | ResizeOptions

Options

OptionTypeDefaultDescription
handlerFunction-Resize event handler (required)
disabledbooleanfalseDisable the directive
box'content-box' | 'border-box' | 'device-pixel-content-box''content-box'Box model to observe
debouncenumber0Debounce time in milliseconds
onFallbackFunction-Callback for browsers without ResizeObserver

Examples

Responsive Layout

vue
<template>
  <div v-resize="handleResize" class="container">
    <div :class="{ 'compact': isCompact }">
      Content adapts to container size
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const isCompact = ref(false)

function handleResize(entry) {
  isCompact.value = entry.contentRect.width < 600
}
</script>

Chart Resize

vue
<template>
  <div v-resize="{ handler: resizeChart, debounce: 100 }" class="chart-container">
    <canvas ref="chartCanvas"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const chartCanvas = ref(null)
let chart = null

onMounted(() => {
  chart = createChart(chartCanvas.value)
})

function resizeChart(entry) {
  if (chart) {
    chart.resize(entry.contentRect.width, entry.contentRect.height)
  }
}
</script>

Text Truncation

vue
<template>
  <div v-resize="checkTruncation" class="text-container">
    <p :title="needsTooltip ? text : ''">{{ text }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const text = 'Long text that might need truncation...'
const needsTooltip = ref(false)

function checkTruncation(entry) {
  const el = entry.target.querySelector('p')
  if (el) {
    needsTooltip.value = el.scrollWidth > el.clientWidth
  }
}
</script>

Composable API

For programmatic use, you can use the useResize composable:

typescript
import { useResize } from 'directix'

const { width, height, bind, stop } = useResize({
  debounce: 0,
  box: 'content-box',
  onResize: (info) => console.log('Resized:', info.width, info.height)
})

// Bind to element
onMounted(() => bind(target.value))

UseResizeOptions

OptionTypeDefaultDescription
debouncenumber | Ref<number>0Debounce time in milliseconds
box'content-box' | 'border-box' | 'device-pixel-content-box''content-box'Box model to observe
onResize(info: ResizeInfo) => void-Callback when resize occurs

UseResizeReturn

PropertyTypeDescription
widthReadonly<Ref<number>>Current width
heightReadonly<Ref<number>>Current height
bind(element: HTMLElement) => () => voidBind resize observer to an element
stop() => voidStop observing

Example

vue
<script setup>
import { ref } from 'vue'
import { useResize } from 'directix'

const target = ref(null)
const { width, height, bind } = useResize({
  debounce: 100,
  onResize: (info) => console.log('Resized:', info.width, info.height)
})

onMounted(() => bind(target.value))
</script>

<template>
  <div ref="target">
    Size: {{ width }} x {{ height }}
  </div>
</template>

Code Generator

Quick Code Generator
<template>
  <div v-resize>
    <!-- Observe element resize using ResizeObserver. directive -->
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// Configure your options here
const options = {}
</script>

Released under the MIT License.