@curi/vue
Version:
Curi plugins and components for Vue.js
154 lines (147 loc) • 4.75 kB
JavaScript
import Vue from 'vue';
function canNavigate(event, target) {
return (!event.defaultPrevented &&
!target &&
(event.button !== undefined && event.button === 0) &&
!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey));
}
var Link = {
name: "curi-link",
props: ["name", "params", "hash", "query", "state", "click"],
computed: {
url: function () {
return this.$router.url({
name: this.name,
params: this.params,
hash: this.hash,
query: this.query
});
}
},
methods: {
clickHandler: function (event) {
if (this.click) {
this.click(event);
}
// @ts-ignore
if (canNavigate(event)) {
event.preventDefault();
this.$router.navigate({
url: this.url,
state: this.state
});
}
}
},
render: function (h) {
return h("a", {
attrs: { href: this.url },
on: { click: this.clickHandler }
}, this.$slots.default);
}
};
var Link$1 = {
name: "curi-async-link",
props: ["name", "params", "hash", "query", "state", "click"],
computed: {
url: function () {
return this.$router.url({
name: this.name,
params: this.params,
hash: this.hash,
query: this.query
});
}
},
data: function () {
return {
navigating: false
};
},
methods: {
clickHandler: function (event) {
var _this = this;
if (this.click) {
this.click(event);
}
// @ts-ignore
if (canNavigate(event)) {
event.preventDefault();
var cancelled = void 0, finished = void 0;
cancelled = finished = function () {
_this.navigating = false;
};
this.navigating = true;
this.$router.navigate({
url: this.url,
state: this.state,
cancelled: cancelled,
finished: finished
});
}
}
},
render: function (h) {
return h("a", {
attrs: { href: this.url },
on: { click: this.clickHandler }
}, this.$scopedSlots.default({
navigating: this.navigating
}));
}
};
function focus(el, options) {
var _a = options.preserve, preserve = _a === void 0 ? false : _a, _b = options.preventScroll, preventScroll = _b === void 0 ? false : _b;
if (preserve && el.contains(document.activeElement)) {
return;
}
setTimeout(function () {
// @ts-ignore
el.focus({ preventScroll: preventScroll });
});
}
var focusDirective = {
inserted: function (el, binding) {
if (process.env.NODE_ENV !== "production") {
if (!el.hasAttribute("tabIndex") && el.tabIndex === -1) {
console.warn('The element that is passed the "v-curi-focus" directive must have a "tabIndex" prop or ' +
"be focusable by default in order to be focused. " +
"Otherwise, the document's <body> will be focused instead.");
}
}
focus(el, binding.value);
},
update: function (el, binding) {
if (binding.value.key !== binding.oldValue.key) {
focus(el, binding.value);
}
}
};
var CuriPlugin = {
install: function (_Vue, options) {
_Vue.component(Link.name, Link);
_Vue.component(Link$1.name, Link$1);
_Vue.directive("curi-focus", focusDirective);
// create a reactive object so that components will receive
// the new response/navigation when a new response is emitted
var reactive = new Vue({
data: options.router.current()
});
options.router.observe(function (_a) {
var response = _a.response, navigation = _a.navigation;
reactive.response = response;
reactive.navigation = navigation;
});
_Vue.mixin({
beforeCreate: function () {
this.$curi = reactive;
}
});
Object.defineProperty(_Vue.prototype, "$router", {
get: function () {
return options.router;
}
});
}
};
export { CuriPlugin };