@nextcloud/vue
Version:
Nextcloud vue components
524 lines (523 loc) • 18.4 kB
JavaScript
require('../assets/NcAppNavigationItem-Kua1hP7u.css');
"use strict";
const _pluginVue2_normalizer = require("./_plugin-vue2_normalizer-V0q-tHlQ.cjs");
const ChevronDown = require("./ChevronDown-BlfyuflD.cjs");
const ChevronUp = require("./ChevronUp-Bpd__OBZ.cjs");
const _l10n = require("./_l10n-DM-VRK9x.cjs");
const NcButton = require("./NcButton-DOsCAjiE.cjs");
const NcInputConfirmCancel = require("./NcInputConfirmCancel-BqZm3WBG.cjs");
const Composables_useIsMobile = require("../Composables/useIsMobile.cjs");
const GenRandomId = require("./GenRandomId-D7iOvpZS.cjs");
const NcActionButton = require("./NcActionButton-CFXzNoFT.cjs");
const NcActions = require("./NcActions-B7oXbiVt.cjs");
const Components_NcLoadingIcon = require("../Components/NcLoadingIcon.cjs");
const Components_NcVNodes = require("../Components/NcVNodes.cjs");
const _sfc_main$3 = {
name: "PencilIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
var _sfc_render$3 = function render() {
var _vm = this, _c = _vm._self._c;
return _c("span", _vm._b({ staticClass: "material-design-icon pencil-icon", attrs: { "aria-hidden": _vm.title ? null : "true", "aria-label": _vm.title, "role": "img" }, on: { "click": function($event) {
return _vm.$emit("click", $event);
} } }, "span", _vm.$attrs, false), [_c("svg", { staticClass: "material-design-icon__svg", attrs: { "fill": _vm.fillColor, "width": _vm.size, "height": _vm.size, "viewBox": "0 0 24 24" } }, [_c("path", { attrs: { "d": "M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" } }, [_vm.title ? _c("title", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);
};
var _sfc_staticRenderFns$3 = [];
var __component__$3 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$3,
_sfc_render$3,
_sfc_staticRenderFns$3,
false,
null,
null
);
const Pencil = __component__$3.exports;
const _sfc_main$2 = {
name: "UndoIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
var _sfc_render$2 = function render2() {
var _vm = this, _c = _vm._self._c;
return _c("span", _vm._b({ staticClass: "material-design-icon undo-icon", attrs: { "aria-hidden": _vm.title ? null : "true", "aria-label": _vm.title, "role": "img" }, on: { "click": function($event) {
return _vm.$emit("click", $event);
} } }, "span", _vm.$attrs, false), [_c("svg", { staticClass: "material-design-icon__svg", attrs: { "fill": _vm.fillColor, "width": _vm.size, "height": _vm.size, "viewBox": "0 0 24 24" } }, [_c("path", { attrs: { "d": "M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z" } }, [_vm.title ? _c("title", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);
};
var _sfc_staticRenderFns$2 = [];
var __component__$2 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$2,
_sfc_render$2,
_sfc_staticRenderFns$2,
false,
null,
null
);
const Undo = __component__$2.exports;
_l10n.register(_l10n.t20);
const _sfc_main$1 = {
name: "NcAppNavigationIconCollapsible",
components: {
NcButton: NcButton.NcButton,
ChevronDown: ChevronDown.ChevronDown,
ChevronUp: ChevronUp.ChevronUp
},
props: {
/**
* Is the list currently open (or collapsed)
*/
open: {
type: Boolean,
// eslint-disable-next-line vue/no-boolean-default
default: true
},
/**
* Is the navigation item currently active.
*/
active: {
type: Boolean,
required: true
}
},
emits: ["click"],
computed: {
labelButton() {
return this.open ? _l10n.t("Collapse menu") : _l10n.t("Open menu");
}
},
methods: {
onClick(e) {
this.$emit("click", e);
}
}
};
var _sfc_render$1 = function render3() {
var _vm = this, _c = _vm._self._c;
return _c("NcButton", { staticClass: "icon-collapse", class: {
"icon-collapse--active": _vm.active,
"icon-collapse--open": _vm.open
}, attrs: { "aria-label": _vm.labelButton, "variant": _vm.active ? "tertiary-on-primary" : "tertiary" }, on: { "click": _vm.onClick }, scopedSlots: _vm._u([{ key: "icon", fn: function() {
return [_vm.open ? _c("ChevronUp", { attrs: { "size": 20 } }) : _c("ChevronDown", { attrs: { "size": 20 } })];
}, proxy: true }]) });
};
var _sfc_staticRenderFns$1 = [];
var __component__$1 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$1,
_sfc_render$1,
_sfc_staticRenderFns$1,
false,
null,
"c8d5bee5"
);
const NcAppNavigationIconCollapsible = __component__$1.exports;
_l10n.register(_l10n.t21, _l10n.t50);
const _sfc_main = {
name: "NcAppNavigationItem",
components: {
NcActions: NcActions.NcActions,
NcActionButton: NcActionButton.NcActionButton,
NcAppNavigationIconCollapsible,
NcInputConfirmCancel: NcInputConfirmCancel.NcInputConfirmCancel,
NcLoadingIcon: Components_NcLoadingIcon,
NcVNodes: Components_NcVNodes,
Pencil,
Undo
},
props: {
/**
* If you are not using vue-router you can use the property to set this item as the active navigation entry.
* When using vue-router and the `to` property this is set automatically.
*/
active: {
type: Boolean,
default: false
},
/**
* The main text content of the entry.
*/
name: {
type: String,
required: true
},
/**
* The title attribute of the element.
*/
title: {
type: String,
default: null
},
/**
* id attribute of the list item element
*/
id: {
type: String,
default: () => "app-navigation-item-" + GenRandomId.GenRandomId(),
validator: (id) => id.trim() !== ""
},
/**
* Refers to the icon on the left, this prop accepts a class
* like 'icon-category-enabled'.
*/
icon: {
type: String,
default: ""
},
/**
* Displays a loading animated icon on the left of the element
* instead of the icon.
*/
loading: {
type: Boolean,
default: false
},
/**
* Passing in a route will make the root element of this
* component a `<router-link />` that points to that route.
* By leaving this blank, the root element will be a `<li>`.
*/
to: {
type: [String, Object],
default: null
},
/**
* A direct link. This will be used as the `href` attribute.
* This will ignore any `to` prop being defined.
*/
href: {
type: String,
default: null
},
/**
* Pass in `true` if you want the matching behaviour to
* be non-inclusive: https://router.vuejs.org/api/#exact
*/
exact: {
type: Boolean,
default: false
},
/**
* Gives the possibility to collapse the children elements into the
* parent element (true) or expands the children elements (false).
*/
allowCollapse: {
type: Boolean,
default: false
},
/**
* Makes the name of the item editable by providing an `ActionButton`
* component that toggles a form
*/
editable: {
type: Boolean,
default: false
},
/**
* Only for 'editable' items, sets label for the edit action button.
*/
editLabel: {
type: String,
default: ""
},
/**
* Only for items in 'editable' mode, sets the placeholder text for the editing form.
*/
editPlaceholder: {
type: String,
default: ""
},
/**
* Pins the item to the bottom left area, above the settings. Do not
* place 'non-pinned' `AppnavigationItem` components below `pinned`
* ones.
*/
pinned: {
type: Boolean,
default: false
},
/**
* Puts the item in the 'undo' state.
*/
undo: {
type: Boolean,
default: false
},
/**
* The navigation collapsible state (synced)
*/
open: {
type: Boolean,
default: false
},
/**
* The actions menu open state (synced)
*/
menuOpen: {
type: Boolean,
default: false
},
/**
* Force the actions to display in a three dot menu
*/
forceMenu: {
type: Boolean,
default: false
},
/**
* The action's menu default icon
*/
menuIcon: {
type: String,
default: void 0
},
/**
* The action's menu direction
*/
menuPlacement: {
type: String,
default: "bottom"
},
/**
* Entry aria details
*/
ariaDescription: {
type: String,
default: null
},
/**
* To be used only when the elements in the actions menu are very important
*/
forceDisplayActions: {
type: Boolean,
default: false
},
/**
* Number of action items outside the menu
*/
inlineActions: {
type: Number,
default: 0
}
},
emits: [
"update:menuOpen",
"update:open",
"update:name",
"click",
"undo"
],
setup() {
return {
isMobile: Composables_useIsMobile.useIsMobile()
};
},
data() {
return {
editingValue: "",
opened: this.open,
// Collapsible state
editingActive: false,
/**
* Tracks the open state of the actions menu
*/
menuOpenLocalValue: false,
focused: false,
actionsBoundariesElement: void 0
};
},
computed: {
isRouterLink() {
return this.to && !this.href;
},
// Checks if the component is already a children of another
// instance of AppNavigationItem
canHaveChildren() {
if (this.$parent.$options._componentTag === "AppNavigationItem") {
return false;
} else {
return true;
}
},
hasUtils() {
if (this.$scopedSlots.actions || this.$scopedSlots.counter || this.editable || this.undo) {
return true;
}
return false;
},
editButtonAriaLabel() {
return this.editLabel ? this.editLabel : _l10n.t("Edit item");
},
undoButtonAriaLabel() {
return _l10n.t("Undo changes");
}
},
watch: {
open(newVal) {
this.opened = newVal;
}
},
mounted() {
this.actionsBoundariesElement = document.querySelector("#content-vue") || void 0;
},
methods: {
// sync opened menu state with prop
onMenuToggle(state) {
this.$emit("update:menuOpen", state);
this.menuOpenLocalValue = state;
},
// toggle the collapsible state
toggleCollapse() {
this.opened = !this.opened;
this.$emit("update:open", this.opened);
},
/**
* Handle link click
*
* @param {PointerEvent} event - Native click event
* @param {Function} [navigate] - VueRouter link's navigate if any
* @param {string} [routerLinkHref] - VueRouter link's href
*/
onClick(event, navigate, routerLinkHref) {
this.$emit("click", event);
if (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) {
return;
}
if (routerLinkHref) {
navigate?.(event);
event.preventDefault();
}
},
// Edition methods
handleEdit() {
this.editingValue = this.name;
this.editingActive = true;
this.onMenuToggle(false);
this.$nextTick(() => {
this.$refs.editingInput.focusInput();
});
},
cancelEditing() {
this.editingActive = false;
},
handleEditingDone() {
this.$emit("update:name", this.editingValue);
this.editingValue = "";
this.editingActive = false;
},
// Undo methods
handleUndo() {
this.$emit("undo");
},
/**
* Does this item have children and is collapsing allowed via the prop?
*
* @return {boolean} True, if the item can be collapsed
*/
isCollapsible() {
return this.allowCollapse && !!this.$scopedSlots.default;
},
/**
* Show actions upon focus
*/
handleFocus() {
this.focused = true;
},
handleBlur() {
this.focused = false;
},
/**
* This method checks if the root element of the component is focused and
* if that's the case it focuses the actions button if available
*
* @param {Event} e the keydown event
*/
handleTab(e) {
if (!this.$refs.actions) {
return;
}
if (this.focused) {
e.preventDefault();
this.$refs.actions.$refs.triggerButton.$el.focus();
this.focused = false;
} else {
this.$refs.actions.$refs.triggerButton.$el.blur();
}
},
/**
* Is this an external link
*
* @param {string} href The link to check
* @return {boolean} Whether it is external or not
*/
isExternal(href) {
return href && href.match(/[a-z]+:\/\//i);
}
}
};
var _sfc_render = function render4() {
var _vm = this, _c = _vm._self._c;
return _c("li", { staticClass: "app-navigation-entry-wrapper", class: {
"app-navigation-entry--opened": _vm.opened,
"app-navigation-entry--pinned": _vm.pinned,
"app-navigation-entry--collapsible": _vm.isCollapsible()
}, attrs: { "id": _vm.id } }, [_c(_vm.isRouterLink ? "router-link" : "NcVNodes", { tag: "component", attrs: { "custom": _vm.isRouterLink ? true : false, "to": _vm.to, "exact": _vm.isRouterLink ? _vm.exact : null }, scopedSlots: _vm._u([{ key: "default", fn: function({ href: routerLinkHref, navigate, isActive }) {
return [_c("div", { staticClass: "app-navigation-entry", class: {
"app-navigation-entry--editing": _vm.editingActive,
"app-navigation-entry--deleted": _vm.undo,
active: _vm.to && isActive || _vm.active
} }, [!_vm.undo ? _c("a", { staticClass: "app-navigation-entry-link", attrs: { "aria-current": _vm.active || _vm.to && isActive ? "page" : void 0, "aria-description": _vm.ariaDescription, "aria-expanded": _vm.$scopedSlots.default ? _vm.opened.toString() : void 0, "href": _vm.href || routerLinkHref || "#", "target": _vm.isExternal(_vm.href) ? "_blank" : void 0, "title": _vm.title || _vm.name }, on: { "blur": _vm.handleBlur, "click": function($event) {
return _vm.onClick($event, navigate, routerLinkHref);
}, "focus": _vm.handleFocus, "keydown": function($event) {
if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "tab", 9, $event.key, "Tab")) return null;
if ($event.ctrlKey || $event.shiftKey || $event.altKey || $event.metaKey) return null;
return _vm.handleTab.apply(null, arguments);
} } }, [_c("div", { staticClass: "app-navigation-entry-icon", class: { [_vm.icon]: _vm.icon } }, [_vm.loading ? _c("NcLoadingIcon") : _vm._t("icon", null, { "active": _vm.active || _vm.to && isActive })], 2), !_vm.editingActive ? _c("span", { staticClass: "app-navigation-entry__name" }, [_vm._v(" " + _vm._s(_vm.name) + " ")]) : _vm._e(), _vm.editingActive ? _c("div", { staticClass: "editingContainer" }, [_c("NcInputConfirmCancel", { ref: "editingInput", attrs: { "placeholder": _vm.editPlaceholder !== "" ? _vm.editPlaceholder : _vm.name, "primary": _vm.to && isActive || _vm.active }, on: { "cancel": _vm.cancelEditing, "confirm": _vm.handleEditingDone }, model: { value: _vm.editingValue, callback: function($$v) {
_vm.editingValue = $$v;
}, expression: "editingValue" } })], 1) : _vm._e()]) : _vm._e(), _vm.undo ? _c("div", { staticClass: "app-navigation-entry__deleted" }, [_c("div", { staticClass: "app-navigation-entry__deleted-description" }, [_vm._v(" " + _vm._s(_vm.name) + " ")])]) : _vm._e(), _vm.hasUtils && !_vm.editingActive ? _c("div", { staticClass: "app-navigation-entry__utils", class: { "app-navigation-entry__utils--display-actions": _vm.forceDisplayActions || _vm.menuOpenLocalValue || _vm.menuOpen } }, [_vm.$scopedSlots.counter ? _c("div", { staticClass: "app-navigation-entry__counter-wrapper" }, [_vm._t("counter")], 2) : _vm._e(), _vm.$scopedSlots.actions || _vm.editable && !_vm.editingActive || _vm.undo ? _c("NcActions", { ref: "actions", staticClass: "app-navigation-entry__actions", attrs: { "inline": _vm.inlineActions, "container": "#app-navigation-vue", "boundaries-element": _vm.actionsBoundariesElement, "placement": _vm.menuPlacement, "open": _vm.menuOpen, "type": _vm.to && isActive || _vm.active ? "tertiary-on-primary" : "tertiary", "force-menu": _vm.forceMenu, "default-icon": _vm.menuIcon }, on: { "update:open": _vm.onMenuToggle }, scopedSlots: _vm._u([{ key: "icon", fn: function() {
return [_vm._t("menu-icon")];
}, proxy: true }], null, true) }, [_vm.editable && !_vm.editingActive ? _c("NcActionButton", { attrs: { "aria-label": _vm.editButtonAriaLabel }, on: { "click": _vm.handleEdit }, scopedSlots: _vm._u([{ key: "icon", fn: function() {
return [_c("Pencil", { attrs: { "size": 20 } })];
}, proxy: true }], null, true) }, [_vm._v(" " + _vm._s(_vm.editLabel) + " ")]) : _vm._e(), _vm.undo ? _c("NcActionButton", { attrs: { "aria-label": _vm.undoButtonAriaLabel }, on: { "click": _vm.handleUndo }, scopedSlots: _vm._u([{ key: "icon", fn: function() {
return [_c("Undo", { attrs: { "size": 20 } })];
}, proxy: true }], null, true) }) : _vm._e(), _vm._t("actions")], 2) : _vm._e()], 1) : _vm._e(), _vm.isCollapsible() ? _c("NcAppNavigationIconCollapsible", { attrs: { "active": _vm.to && isActive || _vm.active, "open": _vm.opened }, on: { "click": function($event) {
$event.preventDefault();
$event.stopPropagation();
return _vm.toggleCollapse.apply(null, arguments);
} } }) : _vm._e(), _vm._t("extra")], 2)];
} }], null, true) }), _vm.canHaveChildren && _vm.$scopedSlots.default ? _c("ul", { staticClass: "app-navigation-entry__children" }, [_vm._t("default")], 2) : _vm._e()], 1);
};
var _sfc_staticRenderFns = [];
var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns,
false,
null,
"587932fa"
);
const NcAppNavigationItem = __component__.exports;
exports.NcAppNavigationItem = NcAppNavigationItem;
//# sourceMappingURL=NcAppNavigationItem-ZOXUMmX5.cjs.map