Skip to content

v-focus

Auto focus an element when mounted.

Since: 1.0.0

Usage

Basic

vue
<template>
  <input v-focus placeholder="Auto focused on mount" />
</template>

With Options

vue
<template>
  <input v-focus="{ focus: true, refocus: true }" />
  <input v-focus="{ onFocus: handleFocus, onBlur: handleBlur }" />
</template>

<script setup>
function handleFocus(el) {
  console.log('Focused:', el)
}

function handleBlur(el) {
  console.log('Blurred:', el)
}
</script>

API

Types

typescript
interface FocusOptions {
  /** Focus element on mount */
  focus?: boolean
  /** Refocus when binding value changes */
  refocus?: boolean
  /** Callback when focused */
  onFocus?: (el: HTMLElement) => void
  /** Callback when blurred */
  onBlur?: (el: HTMLElement) => void
}

type FocusBinding = boolean | FocusOptions

Options

OptionTypeDefaultDescription
focusbooleantrueFocus element on mount
refocusbooleanfalseRefocus when binding value changes
onFocus(el: HTMLElement) => void-Callback when focused
onBlur(el: HTMLElement) => void-Callback when blurred

Examples

vue
<template>
  <button @click="showModal = true">Open Modal</button>

  <div v-if="showModal" class="modal">
    <input v-focus placeholder="Focused when modal opens" />
    <button @click="showModal = false">Close</button>
  </div>
</template>

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

const showModal = ref(false)
</script>

Conditional Focus

vue
<template>
  <div>
    <button @click="editMode = !editMode">
      {{ editMode ? 'Cancel' : 'Edit' }}
    </button>

    <input
      v-if="editMode"
      v-focus="{ focus: true, refocus: true }"
      v-model="text"
    />
    <span v-else>{{ text }}</span>
  </div>
</template>

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

const editMode = ref(false)
const text = ref('Click edit to modify')
</script>

Form with Auto Focus

vue
<template>
  <form @submit.prevent="submit">
    <input v-focus placeholder="First field (auto focused)" />
    <input placeholder="Second field" />
    <input placeholder="Third field" />
    <button type="submit">Submit</button>
  </form>
</template>

<script setup>
function submit() {
  console.log('Form submitted')
}
</script>
vue
<template>
  <div>
    <button @click="showSearch = !showSearch">
      {{ showSearch ? 'Close' : 'Search' }}
    </button>

    <input
      v-if="showSearch"
      v-focus="{ refocus: true }"
      v-debounce:300ms="search"
      placeholder="Search..."
      type="search"
    />
  </div>
</template>

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

const showSearch = ref(false)

function search(event) {
  console.log('Searching:', event.target.value)
}
</script>

Focusable Elements

The directive works with any focusable element:

vue
<template>
  <!-- Input elements -->
  <input v-focus />
  <textarea v-focus></textarea>
  <select v-focus><option>Option</option></select>

  <!-- Button -->
  <button v-focus>Auto focused button</button>

  <!-- Contenteditable -->
  <div v-focus contenteditable="true">Editable content</div>

  <!-- With tabindex -->
  <div v-focus tabindex="0">Focusable div</div>

  <!-- Anchor with href -->
  <a v-focus href="#section">Skip link</a>
</template>

Composable API

For programmatic use, you can use the useFocus composable:

typescript
import { useFocus } from 'directix'

const { isFocused, focus, blur, bind } = useFocus({
  onFocus: (event) => console.log('Focused'),
  onBlur: (event) => console.log('Blurred')
})

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

// Programmatically control focus
focus()
blur()

UseFocusOptions

OptionTypeDefaultDescription
onFocus(event: FocusEvent) => void-Callback when element is focused
onBlur(event: FocusEvent) => void-Callback when element loses focus

UseFocusReturn

PropertyTypeDescription
isFocusedReadonly<Ref<boolean>>Whether the element is currently focused
focus() => voidFocus the element
blur() => voidBlur the element
bind(element: HTMLElement) => () => voidBind focus tracking to an element

Example

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

const input = ref(null)
const { isFocused, focus, bind } = useFocus({
  onBlur: () => validate()
})

onMounted(() => bind(input.value))

function handleButtonClick() {
  focus()
}
</script>

<template>
  <input ref="input" />
  <button @click="focus">Focus Input</button>
  <span v-if="isFocused">Input is focused</span>
</template>

Code Generator

Quick Code Generator
<template>
  <div v-focus="{ delay: 0, disabled: false }">
    <!-- Auto focus an element when mounted. directive -->
  </div>
</template>

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

// Configure your options here
const options = { delay: 0, disabled: false }
</script>

Released under the MIT License.