@undecaf/vue-autofocus
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -1,2 +0,2 @@ | ||
var e={install:function(t){t.directive("autofocus",e)},inserted:function(e,t){function u(e){return e.focus&&e.focus(),document.activeElement===e}(void 0===t.value||t.value)&&setTimeout((function(){if(!u(e))for(var t=0,n=e.querySelectorAll("*");t<n.length;t+=1){if(u(n[t]))return}}),50)}};export default e;export{e as autofocus}; | ||
var e={install:function(t){t.directive("autofocus",e)},inserted:function(e,t){var u;function n(e){return e.focus&&e.focus(),document.activeElement===e}(void 0===t.value||t.value)&&(u="string"==typeof t.value?t.value:"*",setTimeout((function(){if("*"!==u||!n(e))for(var t=0,o=e.querySelectorAll(u);t<o.length;t+=1)if(n(o[t]))return}),50))}};export default e;export{e as autofocus}; | ||
//# sourceMappingURL=directives.esm.js.map |
@@ -1,1 +0,1 @@ | ||
var VueAutofocus=function(e){"use strict";var t,n={install:function(e){e.directive("autofocus",n)},inserted:function(e,t){function n(e){return e.focus&&e.focus(),document.activeElement===e}(void 0===t.value||t.value)&&setTimeout((function(){if(!n(e))for(var t=0,o=e.querySelectorAll("*");t<o.length;t+=1){if(n(o[t]))return}}),50)}},o=Object.freeze({__proto__:null,default:n,autofocus:n});function u(e){if(!u.installed){for(var t in o){var n=o[t];if("function"==typeof n.install)try{n.install(e)}catch(e){console.error("Could not install '"+t+"'",e)}}u.installed=!0}}return"undefined"!=typeof window?t=window.Vue:"undefined"!=typeof global&&(t=global.Vue),t&&t.use({install:u}),e.default=u,e}({});//# sourceMappingURL=directives.min.js.map | ||
var VueAutofocus=function(e){"use strict";var t,n={install:function(e){e.directive("autofocus",n)},inserted:function(e,t){var n;function o(e){return e.focus&&e.focus(),document.activeElement===e}(void 0===t.value||t.value)&&(n="string"==typeof t.value?t.value:"*",setTimeout((function(){if("*"!==n||!o(e))for(var t=0,u=e.querySelectorAll(n);t<u.length;t+=1)if(o(u[t]))return}),50))}},o=Object.freeze({__proto__:null,default:n,autofocus:n});function u(e){if(!u.installed){for(var t in o){var n=o[t];if("function"==typeof n.install)try{n.install(e)}catch(e){console.error("Could not install '"+t+"'",e)}}u.installed=!0}}return"undefined"!=typeof window?t=window.Vue:"undefined"!=typeof global&&(t=global.Vue),t&&t.use({install:u}),e.default=u,e}({});//# sourceMappingURL=directives.min.js.map |
@@ -11,2 +11,4 @@ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});// There are container components that manipulate the focus | ||
inserted: function inserted(el, binding) { | ||
var selector; | ||
function canFocus(element) { | ||
@@ -17,18 +19,20 @@ element.focus && element.focus(); | ||
// Autofocus enabled? | ||
if ((typeof binding.value === 'undefined') || binding.value) { | ||
setTimeout(function () { | ||
if (!canFocus(el)) { | ||
for (var i = 0, list = el.querySelectorAll('*'); i < list.length; i += 1) { | ||
var e = list[i]; | ||
function doFocus() { | ||
if (selector !== '*' || !canFocus(el)) { | ||
for (var i = 0, list = el.querySelectorAll(selector); i < list.length; i += 1) { | ||
var e = list[i]; | ||
if (canFocus(e)) { | ||
return | ||
} | ||
if (canFocus(e)) { | ||
return | ||
} | ||
} | ||
} | ||
} | ||
}, focusDelay); | ||
// Autofocus enabled? | ||
if ((typeof binding.value === 'undefined') || binding.value) { | ||
selector = (typeof binding.value === 'string') ? binding.value : '*'; | ||
setTimeout(doFocus, focusDelay); | ||
} | ||
}, | ||
};exports.autofocus=autofocus;exports.default=autofocus;//# sourceMappingURL=directives.ssr.js.map |
{ | ||
"name": "@undecaf/vue-autofocus", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "A smart Vue autofocus directive", | ||
"keywords": [ | ||
"vue", | ||
"component", | ||
"directive", | ||
"autofocus" | ||
@@ -9,0 +9,0 @@ ], |
# A smart Vue autofocus directive | ||
The directive in this package, `v-autofocus`, tries to be smart in the following way: | ||
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. | ||
Please note that AFAIK only `<text type="hidden">` and elements with attribute `disabled` | ||
are non-focusable; `tabindex="-1"` does not prevent focusing with a mouse. | ||
+ `v-autofocus` works equally well for opaque Vue input components such as the | ||
+ This makes `v-autofocus` work equally well with opaque Vue input components such as the | ||
[Vue Material Datepicker](https://vuematerial.io/components/datepicker), | ||
@@ -17,12 +14,22 @@ [Vue Material Chips](https://vuematerial.io/components/datepicker) and | ||
+ 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](https://vuematerial.io/components/dialog)); | ||
therefore `v-autofocus` acts with a small delay. | ||
therefore `v-autofocus` acts with a small delay (50 ms). | ||
Please note: an element is considered "focusable" if it can become the | ||
[`document.activeElement`](https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement). | ||
Input elements are non-focusable only if hidden or having attribute `disabled`; | ||
elements with `tabindex="-1"` _are_ focusable with a mouse. | ||
+ If a value is assigned to `v-autofocus` then the directive is enabled only if that value is truthy. | ||
## Installation | ||
As a package: | ||
As a module: | ||
@@ -67,3 +74,3 @@ ```shell script | ||
Focusing the first focusable child: | ||
Focusing on the first focusable child: | ||
@@ -80,3 +87,3 @@ ```html | ||
<div> | ||
<!-- This is the first focusable child --> | ||
<!-- First focusable child --> | ||
<textarea v-model="comment"></textarea> | ||
@@ -87,6 +94,27 @@ </div> | ||
Focusing on the first focusable child that matches a selector: | ||
```html | ||
<div v-autofocus=".focus-me"> | ||
<!-- These are not focusable --> | ||
<div><span>Not focusable</span></div> | ||
<img src="#"> | ||
<a></a> | ||
<input type="hidden"> | ||
<input type="text" disabled> | ||
<div> | ||
<!-- First focusable child but will not receive the focus --> | ||
<textarea v-model="comment"></textarea> | ||
<!-- This will receive the focus --> | ||
<input type="text" class="focus-me" v-model="text"> | ||
</div> | ||
</div> | ||
``` | ||
Auto-focusing on a [Vue Material Datepicker](https://vuematerial.io/components/datepicker): | ||
```html | ||
<md-datepicker v-autofocus v-model="birthdate":md-open-on-focus="false" /> | ||
<md-datepicker v-autofocus v-model="birthdate" :md-open-on-focus="false" /> | ||
``` | ||
@@ -93,0 +121,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
15300
37
128