A smart Vue autofocus directive
The directive in this package, v-autofocus
, tries to be smart in the following ways:
-
When placed on a non-focusable element (such as a <div>
) or a Vue component,
it will focus on the first focusable descendant. Descendants are scanned in document order.
-
This makes v-autofocus
work equally well with opaque Vue input components such as the
Vue Material Datepicker,
Vue Material Chips and
Vue Material Autocomplete.
-
In order to be more selective, a string can be assigned to v-autofocus
.
It is interpreted as CSS selector, and the focus will be set on the first matching
focusable descendant.
-
If any value is assigned to v-autofocus
then the directive is enabled only if that
value is truthy.
-
There are container components that manipulate the focus after their children have been
inserted (notably the Vue Material Dialog);
therefore v-autofocus
acts with a small delay (50 ms).
Please note: an element is considered "focusable" if it can become the
document.activeElement
.
Input elements are non-focusable only if hidden or having attribute disabled
;
elements with tabindex="-1"
are focusable with a mouse.
Installation
As a module:
$ npm install @undecaf/vue-autofocus
or
$ yarn add @undecaf/vue-autofocus
Included as <script>
:
<script src="https://cdn.jsdelivr.net/npm/@undecaf/vue-autofocus/dist/directives.min.js"></script>
Usage
Registering the directive
import autofocus from 'vue-autofocus'
Vue.use(autofocus)
Examples
A simple use case:
<input type="text" v-autofocus>
Conditional autofocus:
<input type="text" v-autofocus="focusMe">
Focusing on the first focusable child:
<div v-autofocus>
<div><span>Not focusable</span></div>
<img src="#">
<a></a>
<input type="hidden">
<input type="text" disabled>
<div>
<textarea v-model="comment"></textarea>
</div>
</div>
Focusing on the first focusable child that matches a selector:
<div v-autofocus=".focus-me">
<div><span>Not focusable</span></div>
<img src="#">
<a></a>
<input type="hidden">
<input type="text" disabled>
<div>
<textarea v-model="comment"></textarea>
<input type="text" class="focus-me" v-model="text">
</div>
</div>
Auto-focusing on a Vue Material Datepicker:
<md-datepicker v-autofocus v-model="birthdate" :md-open-on-focus="false" />
This will have no effect:
<div v-autofocus></div>
License
MIT