From 26bbb8c0e4c2a0c9718368d2e316fbb9eadb52fc Mon Sep 17 00:00:00 2001 From: Christopher Ng Date: Mon, 11 Mar 2024 16:26:41 -0700 Subject: [PATCH 1/4] fix(files): Right click menu scroll reset glitch Signed-off-by: Christopher Ng --- apps/files/src/components/FilesListVirtual.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index b6a11391dc1f4..ffa17240fe001 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -326,7 +326,6 @@ export default defineComponent({ --clickable-area: 44px; --icon-preview-size: 32px; - position: relative; overflow: auto; height: 100%; will-change: scroll-position; From 742e5b6329fac3bdbe1d6f246d7a9c09765fed1d Mon Sep 17 00:00:00 2001 From: Christopher Ng Date: Tue, 12 Mar 2024 12:10:16 -0700 Subject: [PATCH 2/4] fix(files): Right click menu positioning Signed-off-by: Christopher Ng --- apps/files/src/components/FileEntry/FileEntryActions.vue | 5 +++-- apps/files/src/components/FileEntryMixin.ts | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/files/src/components/FileEntry/FileEntryActions.vue b/apps/files/src/components/FileEntry/FileEntryActions.vue index 87ffef1fa3a4a..ff28369049b95 100644 --- a/apps/files/src/components/FileEntry/FileEntryActions.vue +++ b/apps/files/src/components/FileEntry/FileEntryActions.vue @@ -352,12 +352,13 @@ export default Vue.extend({ \n * ```\n */\n navigationClasses: {\n type: [String, Array, Object],\n required: !1,\n default: \"\"\n },\n /**\n * aria-label for the dialog navigation.\n * Use it when you want to provide a more meaningful label than the dialog name.\n *\n * By default, navigation is labeled by the dialog name.\n */\n navigationAriaLabel: {\n type: String,\n required: !1,\n default: \"\"\n },\n /**\n * aria-labelledby for the dialog navigation.\n * Use it when you have an implicit navigation label (e.g. a heading).\n *\n * By default, navigation is labeled by the dialog name.\n */\n navigationAriaLabelledby: {\n type: String,\n required: !1,\n default: \"\"\n },\n /**\n * Optionally pass additionaly classes which will be set on the content wrapper for custom styling\n * @default ''\n */\n contentClasses: {\n type: [String, Array, Object],\n required: !1,\n default: \"\"\n },\n /**\n * Optionally pass additionaly classes which will be set on the dialog itself\n * (the default `class` attribute will be set on the modal wrapper)\n * @default ''\n */\n dialogClasses: {\n type: [String, Array, Object],\n required: !1,\n default: \"\"\n }\n },\n emits: [\"closing\", \"update:open\"],\n setup(e, { emit: a, slots: t }) {\n const i = s(), { width: l } = m(i, { width: 900 }), u = n(() => l.value < 876), f = n(() => (t == null ? void 0 : t.navigation) !== void 0), r = s(A()), g = n(() => e.navigationAriaLabel || void 0), p = n(() => {\n if (!e.navigationAriaLabel)\n return e.navigationAriaLabelledby || r.value;\n }), o = s(!0), _ = () => {\n d(), window.setTimeout(() => c(), 300);\n }, d = () => {\n o.value = !1, a(\"closing\");\n }, c = () => {\n o.value = !0, a(\"update:open\", !1);\n }, v = n(() => ({\n canClose: e.canClose,\n container: e.container === void 0 ? \"body\" : e.container,\n // we do not pass the name as we already have the name as the headline\n // name: props.name,\n size: e.size,\n show: e.open && o.value,\n outTransition: e.outTransition,\n closeOnClickOutside: e.closeOnClickOutside,\n additionalTrapElements: e.additionalTrapElements\n }));\n return {\n handleButtonClose: _,\n handleClosing: d,\n handleClosed: c,\n hasNavigation: f,\n navigationId: r,\n navigationAriaLabelAttr: g,\n navigationAriaLabelledbyAttr: p,\n isNavigationCollapsed: u,\n modalProps: v,\n wrapper: i\n };\n }\n});\nvar w = function() {\n var a = this, t = a._self._c;\n return a._self._setupProxy, a.open ? t(\"NcModal\", a._b({ staticClass: \"dialog__modal\", attrs: { \"enable-slideshow\": !1, \"enable-swipe\": !1 }, on: { close: a.handleClosed, \"update:show\": a.handleClosing } }, \"NcModal\", a.modalProps, !1), [t(\"h2\", { staticClass: \"dialog__name\", attrs: { id: a.navigationId }, domProps: { textContent: a._s(a.name) } }), t(\"div\", { staticClass: \"dialog\", class: a.dialogClasses }, [t(\"div\", { ref: \"wrapper\", class: [\"dialog__wrapper\", { \"dialog__wrapper--collapsed\": a.isNavigationCollapsed }] }, [a.hasNavigation ? t(\"nav\", { staticClass: \"dialog__navigation\", class: a.navigationClasses, attrs: { \"aria-label\": a.navigationAriaLabelAttr, \"aria-labelledby\": a.navigationAriaLabelledbyAttr } }, [a._t(\"navigation\", null, { isCollapsed: a.isNavigationCollapsed })], 2) : a._e(), t(\"div\", { staticClass: \"dialog__content\", class: a.contentClasses }, [a._t(\"default\", function() {\n return [t(\"p\", { staticClass: \"dialog__text\" }, [a._v(\" \" + a._s(a.message) + \" \")])];\n })], 2)]), t(\"div\", { staticClass: \"dialog__actions\" }, [a._t(\"actions\", function() {\n return a._l(a.buttons, function(i, l) {\n return t(\"NcDialogButton\", a._b({ key: l, on: { click: a.handleButtonClose } }, \"NcDialogButton\", i, !1));\n });\n })], 2)])]) : a._e();\n}, L = [], S = /* @__PURE__ */ h(\n N,\n w,\n L,\n !1,\n null,\n \"40a87f52\",\n null,\n null\n);\nconst z = S.exports;\nexport {\n z as N\n};\n","import { defineComponent as o } from \"vue\";\nimport l from \"../Components/NcButton.mjs\";\nimport { N as i } from \"./NcIconSvgWrapper-BTdzvQGV.mjs\";\nimport { n as a } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nconst u = o({\n name: \"NcDialogButton\",\n components: {\n NcButton: l,\n NcIconSvgWrapper: i\n },\n props: {\n /**\n * The function that will be called when the button is pressed\n * @type {() => void}\n */\n callback: {\n type: Function,\n required: !0\n },\n /**\n * The label of the button\n */\n label: {\n type: String,\n required: !0\n },\n /**\n * Optional inline SVG icon for the button\n */\n icon: {\n type: String,\n required: !1,\n default: void 0\n },\n /**\n * The button type, see NcButton\n * @type {'primary'|'secondary'|'error'|'warning'|'success'}\n */\n type: {\n type: String,\n required: !1,\n default: \"secondary\",\n validator: (n) => typeof n == \"string\" && [\"primary\", \"secondary\", \"error\", \"warning\", \"success\"].includes(n)\n }\n },\n emits: [\"click\"],\n setup(n, { emit: e }) {\n return { handleClick: (c) => {\n var t;\n (t = n.callback) == null || t.call(n), e(\"click\", c);\n } };\n }\n});\nvar s = function() {\n var e = this, r = e._self._c;\n return e._self._setupProxy, r(\"NcButton\", { attrs: { \"aria-label\": e.label, type: e.type }, on: { click: e.handleClick }, scopedSlots: e._u([{ key: \"icon\", fn: function() {\n return [e._t(\"icon\", function() {\n return [e.icon !== void 0 ? r(\"NcIconSvgWrapper\", { attrs: { svg: e.icon } }) : e._e()];\n })];\n }, proxy: !0 }], null, !0) }, [e._v(\" \" + e._s(e.label) + \" \")]);\n}, d = [], f = /* @__PURE__ */ a(\n u,\n s,\n d,\n !1,\n null,\n null,\n null,\n null\n);\nconst g = f.exports;\nexport {\n g as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcEmojiPicker-B-4WNYcx.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcEmojiPicker-B-4WNYcx.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcEmojiPicker-B-4WNYcx.css';\nimport { Emoji as u, Picker as f, EmojiIndex as p } from \"emoji-mart-vue-fast\";\nimport { r as m, u as d, v as h, w as k, a as n } from \"./_l10n-CAwwH-o2.mjs\";\nimport { g as v, s as _ } from \"./emoji-k4gWHxrE.mjs\";\nimport { C as o } from \"./GenColors-SIdMEx1i.mjs\";\nimport y from \"emoji-mart-vue-fast/data/all.json\";\nimport { n as c } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nimport g from \"../Components/NcButton.mjs\";\nimport { N as S } from \"./NcColorPicker-sge8Yr9m.mjs\";\nimport { N as w } from \"./NcPopover--V3R3EKV.mjs\";\nimport { N as C } from \"./NcTextField-BEpgHsY2.mjs\";\nm(k, h, d);\nconst b = {\n name: \"CircleIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar j = function() {\n var e = this, t = e._self._c;\n return t(\"span\", e._b({ staticClass: \"material-design-icon circle-icon\", attrs: { \"aria-hidden\": e.title ? null : !0, \"aria-label\": e.title, role: \"img\" }, on: { click: function(i) {\n return e.$emit(\"click\", i);\n } } }, \"span\", e.$attrs, !1), [t(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { fill: e.fillColor, width: e.size, height: e.size, viewBox: \"0 0 24 24\" } }, [t(\"path\", { attrs: { d: \"M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\" } }, [e.title ? t(\"title\", [e._v(e._s(e.title))]) : e._e()])])]);\n}, $ = [], N = /* @__PURE__ */ c(\n b,\n j,\n $,\n !1,\n null,\n null,\n null,\n null\n);\nconst E = N.exports;\nlet a;\nconst P = {\n search: n(\"Search emoji\"),\n notfound: n(\"No emoji found\"),\n categories: {\n search: n(\"Search results\"),\n recent: n(\"Frequently used\"),\n smileys: n(\"Smileys & Emotion\"),\n people: n(\"People & Body\"),\n nature: n(\"Animals & Nature\"),\n foods: n(\"Food & Drink\"),\n activity: n(\"Activities\"),\n places: n(\"Travel & Places\"),\n objects: n(\"Objects\"),\n symbols: n(\"Symbols\"),\n flags: n(\"Flags\"),\n custom: n(\"Custom\")\n }\n}, l = [\n new o(255, 222, 52, n(\"Neutral skin color\")),\n new o(228, 205, 166, n(\"Light skin tone\")),\n new o(250, 221, 192, n(\"Medium light skin tone\")),\n new o(174, 129, 87, n(\"Medium skin tone\")),\n new o(158, 113, 88, n(\"Medium dark skin tone\")),\n new o(96, 79, 69, n(\"Dark skin tone\"))\n], x = {\n name: \"NcEmojiPicker\",\n components: {\n Emoji: u,\n IconCircle: E,\n NcButton: g,\n NcColorPicker: S,\n NcPopover: w,\n NcTextField: C,\n Picker: f\n },\n props: {\n /**\n * The emoji-set\n */\n activeSet: {\n type: String,\n default: \"native\"\n },\n /**\n * Show preview section when hovering emoji\n */\n showPreview: {\n type: Boolean,\n default: !1\n },\n /**\n * Allow unselecting the selected emoji\n */\n allowUnselect: {\n type: Boolean,\n default: !1\n },\n /**\n * Selected emoji to allow unselecting\n */\n selectedEmoji: {\n type: String,\n default: \"\"\n },\n /**\n * The fallback emoji in the preview section\n */\n previewFallbackEmoji: {\n type: String,\n default: \"grinning\"\n },\n /**\n * The fallback text in the preview section\n */\n previewFallbackName: {\n type: String,\n default: n(\"Pick an emoji\")\n },\n /**\n * Whether to close the emoji picker after picking one\n */\n closeOnSelect: {\n type: Boolean,\n default: !0\n },\n /**\n * Selector for the popover container\n */\n container: {\n type: [String, Object, Element, Boolean],\n default: \"body\"\n }\n },\n emits: [\n \"select\",\n \"select-data\",\n \"unselect\"\n ],\n setup() {\n return a || (a = new p(y)), {\n // Non-reactive constants\n emojiIndex: a,\n skinTonePalette: l,\n i18n: P\n };\n },\n data() {\n const r = v();\n return {\n /**\n * The current active color from the skin tone palette\n */\n currentColor: l[r - 1],\n /**\n * The current active skin tone\n * @type {1|2|3|4|5|6}\n */\n currentSkinTone: r,\n search: \"\",\n open: !1\n };\n },\n computed: {\n native() {\n return this.activeSet === \"native\";\n }\n },\n methods: {\n t: n,\n clearSearch() {\n var e, t;\n this.search = \"\";\n const r = (t = (e = this.$refs.search) == null ? void 0 : e.$refs.inputField) == null ? void 0 : t.$refs.input;\n r && r.focus();\n },\n /**\n * Update the current skin tone by the result of the color picker\n * @param {string} color Color set\n */\n onChangeSkinTone(r) {\n const e = this.skinTonePalette.findIndex((t) => t.color.toLowerCase() === r.toLowerCase());\n e > -1 && (this.currentSkinTone = e + 1, this.currentColor = this.skinTonePalette[e], _(this.currentSkinTone));\n },\n select(r) {\n this.$emit(\"select\", r.native), this.$emit(\"select-data\", r), this.closeOnSelect && (this.open = !1);\n },\n unselect() {\n this.$emit(\"unselect\");\n },\n afterShow() {\n var t, i;\n this.$refs.picker.$el.addEventListener(\"keydown\", this.checkKeyEvent);\n const e = (i = (t = this.$refs.search) == null ? void 0 : t.$refs.inputField) == null ? void 0 : i.$refs.input;\n e && e.focus();\n },\n afterHide() {\n this.$refs.picker.$el.removeEventListener(\"keydown\", this.checkKeyEvent);\n },\n checkKeyEvent(r) {\n if (r.key !== \"Tab\")\n return;\n const t = this.$refs.picker.$el.querySelectorAll(\n \"button, input\"\n ), i = t.length - 1;\n if (t.length <= 1) {\n r.preventDefault();\n return;\n }\n r.shiftKey === !1 && r.target === t[i] ? (r.preventDefault(), t[0].focus()) : r.shiftKey === !0 && r.target === t[0] && (r.preventDefault(), t[i].focus());\n }\n }\n};\nvar T = function() {\n var e = this, t = e._self._c;\n return t(\"NcPopover\", e._g(e._b({ attrs: { shown: e.open, container: e.container, \"popup-role\": \"dialog\" }, on: { \"update:shown\": function(i) {\n e.open = i;\n }, \"after-show\": e.afterShow, \"after-hide\": e.afterHide }, scopedSlots: e._u([{ key: \"trigger\", fn: function(i) {\n return [e._t(\"default\", null, null, i)];\n } }], null, !0) }, \"NcPopover\", e.$attrs, !1), e.$listeners), [t(\"Picker\", e._b({ ref: \"picker\", attrs: { \"auto-focus\": !1, color: \"var(--color-primary-element)\", data: e.emojiIndex, emoji: e.previewFallbackEmoji, i18n: e.i18n, native: e.native, \"emoji-size\": 20, \"per-line\": 8, \"picker-styles\": { width: \"320px\" }, \"show-preview\": e.showPreview, skin: e.currentSkinTone, \"show-skin-tones\": !1, title: e.previewFallbackName, role: \"dialog\", \"aria-modal\": \"true\", \"aria-label\": e.t(\"Emoji picker\") }, on: { select: e.select }, scopedSlots: e._u([{ key: \"searchTemplate\", fn: function(i) {\n return [t(\"div\", { staticClass: \"search__wrapper\" }, [t(\"NcTextField\", { ref: \"search\", staticClass: \"search\", attrs: { value: e.search, label: e.t(\"Search\"), \"label-visible\": !0, placeholder: e.i18n.search, \"trailing-button-icon\": \"close\", \"trailing-button-label\": e.t(\"Clear search\"), \"show-trailing-button\": e.search !== \"\" }, on: { \"update:value\": [function(s) {\n e.search = s;\n }, function(s) {\n return i.onSearch(e.search);\n }], \"trailing-button-click\": function(s) {\n e.clearSearch(), i.onSearch(e.search);\n } } }), t(\"NcColorPicker\", { attrs: { \"palette-only\": \"\", container: e.container, palette: e.skinTonePalette, value: e.currentColor.color }, on: { \"update:value\": e.onChangeSkinTone } }, [t(\"NcButton\", { attrs: { \"aria-label\": e.t(\"Skin tone\"), type: \"tertiary-no-background\" }, scopedSlots: e._u([{ key: \"icon\", fn: function() {\n return [t(\"IconCircle\", { style: { color: e.currentColor.color }, attrs: { title: e.currentColor.name, size: 20 } })];\n }, proxy: !0 }], null, !0) })], 1)], 1)];\n } }, e.allowUnselect && e.selectedEmoji ? { key: \"customCategory\", fn: function() {\n return [t(\"div\", { staticClass: \"emoji-mart-category-label\" }, [t(\"h3\", { staticClass: \"emoji-mart-category-label\" }, [e._v(\" \" + e._s(e.t(\"Selected\")) + \" \")])]), t(\"Emoji\", { staticClass: \"emoji-selected\", attrs: { data: e.emojiIndex, emoji: e.selectedEmoji, native: !0, size: 32 }, on: { click: e.unselect } }), t(\"Emoji\", { staticClass: \"emoji-delete\", attrs: { data: e.emojiIndex, emoji: \":x:\", native: !0, size: 10 }, on: { click: e.unselect } })];\n }, proxy: !0 } : null], null, !0) }, \"Picker\", e.$attrs, !1))], 1);\n}, F = [], I = /* @__PURE__ */ c(\n x,\n T,\n F,\n !1,\n null,\n \"54cb91eb\",\n null,\n null\n);\nconst R = I.exports;\nexport {\n R as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcHeaderMenu-BKufmJd0.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcHeaderMenu-BKufmJd0.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcMentionBubble-BhiXWJv8.css';\nimport '../assets/NcHeaderMenu-BKufmJd0.css';\nimport { vOnClickOutside as n } from \"@vueuse/components\";\nimport { createFocusTrap as o } from \"focus-trap\";\nimport { G as s } from \"./GenRandomId-BW3iYFf9.mjs\";\nimport a from \"../Mixins/clickOutsideOptions.mjs\";\nimport \"../Composables/useIsFullscreen.mjs\";\nimport \"../Composables/useIsMobile.mjs\";\nimport \"@nextcloud/router\";\n/* empty css */\nimport { n as c } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nimport \"linkify-string\";\nimport \"escape-html\";\nimport \"striptags\";\nimport \"vue\";\nimport \"@nextcloud/auth\";\nimport \"@nextcloud/axios\";\nimport \"@nextcloud/capabilities\";\nimport { g as u } from \"./focusTrap-Be9GEB5C.mjs\";\nimport d from \"../Components/NcButton.mjs\";\nconst l = {\n name: \"NcHeaderMenu\",\n components: {\n NcButton: d\n },\n directives: {\n ClickOutside: n\n },\n mixins: [\n a\n ],\n props: {\n /**\n * Unique id for this menu\n */\n id: {\n type: String,\n required: !0\n },\n /**\n * aria-label attribute of the menu open button\n */\n ariaLabel: {\n type: String,\n default: \"\"\n },\n /**\n * Current menu open state\n */\n open: {\n type: Boolean,\n default: !1\n },\n /**\n * Pass `true` if the header menu is used for website navigation\n *\n * The wrapper tag will be set to `nav` and its `aria-labelledby`\n * will be associated with the menu open button\n */\n isNav: {\n type: Boolean,\n default: !1\n },\n /**\n * Additional visually hidden description text for the menu\n * open button\n */\n description: {\n type: String,\n default: null\n }\n },\n emits: [\n \"close\",\n \"closed\",\n \"open\",\n \"opened\",\n \"update:open\",\n \"cancel\"\n ],\n data() {\n var t, e, i;\n return {\n focusTrap: null,\n opened: this.open,\n shortcutsDisabled: (i = (e = (t = window.OCP) == null ? void 0 : t.Accessibility) == null ? void 0 : e.disableKeyboardShortcuts) == null ? void 0 : i.call(e),\n triggerId: s(),\n descriptionId: s()\n };\n },\n computed: {\n wrapperTag() {\n return this.isNav ? \"nav\" : \"div\";\n },\n clickOutsideConfig() {\n return [\n this.closeMenu,\n this.clickOutsideOptions\n ];\n },\n listeners() {\n return this.isNav ? {\n focusout: this.onFocusOut\n } : null;\n }\n },\n watch: {\n open(t) {\n t ? this.openMenu() : this.closeMenu();\n }\n },\n mounted() {\n document.addEventListener(\"keydown\", this.onKeyDown);\n },\n beforeDestroy() {\n document.removeEventListener(\"keydown\", this.onKeyDown);\n },\n methods: {\n /**\n * Toggle the current menu open state\n */\n toggleMenu() {\n this.opened ? this.closeMenu() : this.openMenu();\n },\n /**\n * Close the current menu\n *\n * @param {boolean} cancelled emit a cancel event instead of close\n */\n closeMenu(t = !1) {\n this.opened = !1, this.$emit(t ? \"cancel\" : \"close\"), this.$emit(\"update:open\", !1), this.clearFocusTrap(), this.$nextTick(() => {\n this.$emit(\"closed\");\n });\n },\n /**\n * Open the current menu\n */\n openMenu() {\n this.opened = !0, this.$emit(\"open\"), this.$emit(\"update:open\", !0), this.$nextTick(() => {\n this.useFocusTrap(), this.$emit(\"opened\");\n });\n },\n onKeyDown(t) {\n this.shortcutsDisabled || !this.opened || t.key === \"Escape\" && (t.preventDefault(), this.closeMenu(!0));\n },\n /**\n * @param {FocusEvent} event The focus event\n */\n onFocusOut(t) {\n this.$refs.headerMenu.contains(t.relatedTarget) || this.closeMenu();\n },\n /**\n * Add focus trap for accessibility.\n * Shall only be used when all children are mounted\n * and available in the DOM. We use $nextTick for that.\n */\n async useFocusTrap() {\n if (this.isNav || this.focusTrap)\n return;\n const t = this.$refs.content;\n this.focusTrap = o(t, {\n allowOutsideClick: !0,\n trapStack: u(),\n fallbackFocus: this.$refs.trigger\n }), this.focusTrap.activate();\n },\n clearFocusTrap() {\n var t;\n (t = this.focusTrap) == null || t.deactivate(), this.focusTrap = null;\n }\n }\n};\nvar p = function() {\n var e = this, i = e._self._c;\n return i(e.wrapperTag, e._g({ directives: [{ name: \"click-outside\", rawName: \"v-click-outside\", value: e.clickOutsideConfig, expression: \"clickOutsideConfig\" }], ref: \"headerMenu\", tag: \"component\", staticClass: \"header-menu\", class: { \"header-menu--opened\": e.opened }, attrs: { id: e.id, \"aria-labelledby\": e.isNav ? e.triggerId : null } }, e.listeners), [i(\"NcButton\", { ref: \"trigger\", staticClass: \"header-menu__trigger\", attrs: { id: e.isNav ? e.triggerId : null, type: \"tertiary-no-background\", \"aria-label\": e.ariaLabel, \"aria-describedby\": e.description ? e.descriptionId : null, \"aria-controls\": \"header-menu-\".concat(e.id), \"aria-expanded\": e.opened.toString() }, on: { click: function(r) {\n return r.preventDefault(), e.toggleMenu.apply(null, arguments);\n } }, scopedSlots: e._u([{ key: \"icon\", fn: function() {\n return [e._t(\"trigger\")];\n }, proxy: !0 }], null, !0) }), e.description ? i(\"span\", { staticClass: \"header-menu__description hidden-visually\", attrs: { id: e.descriptionId } }, [e._v(\" \" + e._s(e.description) + \" \")]) : e._e(), i(\"div\", { directives: [{ name: \"show\", rawName: \"v-show\", value: e.opened, expression: \"opened\" }], staticClass: \"header-menu__carret\" }), i(\"div\", { directives: [{ name: \"show\", rawName: \"v-show\", value: e.opened, expression: \"opened\" }], staticClass: \"header-menu__wrapper\", attrs: { id: \"header-menu-\".concat(e.id) } }, [i(\"div\", { ref: \"content\", staticClass: \"header-menu__content\" }, [e._t(\"default\")], 2)])], 1);\n}, m = [], h = /* @__PURE__ */ c(\n l,\n p,\n m,\n !1,\n null,\n \"7103b917\",\n null,\n null\n);\nconst I = h.exports;\nexport {\n I as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcIconSvgWrapper-oui2KPBT.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcIconSvgWrapper-oui2KPBT.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcIconSvgWrapper-oui2KPBT.css';\nimport a, { useCssVars as o } from \"vue\";\nimport u from \"dompurify\";\nimport { n as p } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nconst r = {\n name: \"NcIconSvgWrapper\",\n props: {\n /**\n * Set if the icon should be used as inline content e.g. within text.\n * By default the icon is made a block element for use inside `icon`-slots.\n */\n inline: {\n type: Boolean,\n default: !1\n },\n /**\n * Raw SVG string to render\n */\n svg: {\n type: String,\n default: \"\"\n },\n /**\n * Label of the icon, used in aria-label\n */\n name: {\n type: String,\n default: \"\"\n },\n /**\n * Raw SVG path to render. Takes precedence over the SVG string in the `svg` prop.\n */\n path: {\n type: String,\n default: \"\"\n },\n /**\n * Size of the icon to show. Only use if not using within an icon slot.\n * Defaults to 20px which is the Nextcloud icon size for all icon slots.\n * @default 20\n */\n size: {\n type: [Number, String],\n default: 20,\n validator: (t) => typeof t == \"number\" || t === \"auto\"\n }\n },\n computed: {\n /**\n * Icon size used in CSS\n */\n iconSize() {\n return typeof this.size == \"number\" ? \"\".concat(this.size, \"px\") : this.size;\n },\n cleanSvg() {\n if (!this.svg || this.path)\n return;\n const t = u.sanitize(this.svg), e = new DOMParser().parseFromString(t, \"image/svg+xml\");\n return e.querySelector(\"parsererror\") ? (a.util.warn(\"SVG is not valid\"), \"\") : (e.documentElement.id && e.documentElement.removeAttribute(\"id\"), e.documentElement.outerHTML);\n },\n attributes() {\n return {\n class: [\"icon-vue\", { \"icon-vue--inline\": this.inline }],\n role: \"img\",\n \"aria-hidden\": this.name ? void 0 : !0,\n \"aria-label\": this.name || void 0\n };\n }\n }\n}, s = () => {\n o((t, e) => ({\n \"758c7a6a\": t.iconSize\n }));\n}, i = r.setup;\nr.setup = i ? (t, e) => (s(), i(t, e)) : s;\nconst l = r;\nvar c = function() {\n var e = this, n = e._self._c;\n return e.cleanSvg ? n(\"span\", e._b({ domProps: { innerHTML: e._s(e.cleanSvg) } }, \"span\", e.attributes, !1)) : n(\"span\", e._b({}, \"span\", e.attributes, !1), [n(\"svg\", { attrs: { viewBox: \"0 0 24 24\", xmlns: \"http://www.w3.org/2000/svg\" } }, [n(\"path\", { attrs: { d: e.path } })])]);\n}, m = [], _ = /* @__PURE__ */ p(\n l,\n c,\n m,\n !1,\n null,\n \"74df2152\",\n null,\n null\n);\nconst g = _.exports;\nexport {\n g as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcInputConfirmCancel-CSzzPx0i.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcInputConfirmCancel-CSzzPx0i.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcInputConfirmCancel-CSzzPx0i.css';\nimport o from \"../Components/NcButton.mjs\";\nimport { r as i, m as l, a } from \"./_l10n-CAwwH-o2.mjs\";\nimport { A as u } from \"./ArrowRight-C3BxTDjF.mjs\";\nimport { C as c } from \"./Close-BtO5TPBO.mjs\";\nimport { n as p } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\ni(l);\nconst s = {\n name: \"NcInputConfirmCancel\",\n components: {\n NcButton: o,\n ArrowRight: u,\n Close: c\n },\n props: {\n /**\n * If this element is used on a primary element set to true for primary styling.\n */\n primary: {\n default: !1,\n type: Boolean\n },\n placeholder: {\n default: \"\",\n type: String\n },\n value: {\n default: \"\",\n type: String\n }\n },\n emits: [\n \"input\",\n \"confirm\",\n \"cancel\"\n ],\n data() {\n return {\n labelConfirm: a(\"Confirm changes\"),\n labelCancel: a(\"Cancel changes\")\n };\n },\n computed: {\n valueModel: {\n get() {\n return this.value;\n },\n set(r) {\n this.$emit(\"input\", r);\n }\n }\n },\n methods: {\n confirm() {\n this.$emit(\"confirm\");\n },\n cancel() {\n this.$emit(\"cancel\");\n },\n focusInput() {\n this.$refs.input.focus();\n }\n }\n};\nvar f = function() {\n var e = this, n = e._self._c;\n return n(\"div\", { staticClass: \"app-navigation-input-confirm\" }, [n(\"form\", { on: { submit: function(t) {\n return t.preventDefault(), e.confirm.apply(null, arguments);\n }, keydown: function(t) {\n return !t.type.indexOf(\"key\") && e._k(t.keyCode, \"esc\", 27, t.key, [\"Esc\", \"Escape\"]) || t.ctrlKey || t.shiftKey || t.altKey || t.metaKey ? null : (t.stopPropagation(), t.preventDefault(), e.cancel.apply(null, arguments));\n }, click: function(t) {\n t.stopPropagation(), t.preventDefault();\n } } }, [n(\"input\", { directives: [{ name: \"model\", rawName: \"v-model\", value: e.valueModel, expression: \"valueModel\" }], ref: \"input\", staticClass: \"app-navigation-input-confirm__input\", attrs: { type: \"text\", placeholder: e.placeholder }, domProps: { value: e.valueModel }, on: { input: function(t) {\n t.target.composing || (e.valueModel = t.target.value);\n } } }), n(\"NcButton\", { attrs: { \"native-type\": \"submit\", type: \"primary\", \"aria-label\": e.labelConfirm }, on: { click: function(t) {\n return t.stopPropagation(), t.preventDefault(), e.confirm.apply(null, arguments);\n } }, scopedSlots: e._u([{ key: \"icon\", fn: function() {\n return [n(\"ArrowRight\", { attrs: { size: 20 } })];\n }, proxy: !0 }]) }), n(\"NcButton\", { attrs: { \"native-type\": \"reset\", type: e.primary ? \"primary\" : \"tertiary\", \"aria-label\": e.labelCancel }, on: { click: function(t) {\n return t.stopPropagation(), t.preventDefault(), e.cancel.apply(null, arguments);\n } }, scopedSlots: e._u([{ key: \"icon\", fn: function() {\n return [n(\"Close\", { attrs: { size: 20 } })];\n }, proxy: !0 }]) })], 1)]);\n}, m = [], y = /* @__PURE__ */ p(\n s,\n f,\n m,\n !1,\n null,\n \"dcf0becf\",\n null,\n null\n);\nconst v = y.exports;\nexport {\n v as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcListItem-DLFj1G31.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcListItem-DLFj1G31.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcListItem-DLFj1G31.css';\nimport { N as l } from \"./NcActions-D2wvJbMw.mjs\";\nimport r from \"../Components/NcCounterBubble.mjs\";\nimport c from \"../Components/NcVNodes.mjs\";\nimport { r as u, h as d, a as h } from \"./_l10n-CAwwH-o2.mjs\";\nimport { n as m } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nu(d);\nconst f = {\n name: \"NcListItem\",\n components: {\n NcActions: l,\n NcCounterBubble: r,\n NcVNodes: c\n },\n props: {\n /**\n * The details text displayed in the upper right part of the component\n */\n details: {\n type: String,\n default: \"\"\n },\n /**\n * Name (first line of text)\n */\n name: {\n type: String,\n required: !0\n },\n /**\n * Pass in `true` if you want the matching behavior to\n * be non-inclusive: https://router.vuejs.org/api/#exact\n */\n exact: {\n type: Boolean,\n default: !1\n },\n /**\n * The route for the router link.\n */\n to: {\n type: [String, Object],\n default: null\n },\n /**\n * The value for the external link\n */\n href: {\n type: String,\n default: \"#\"\n },\n target: {\n type: String,\n default: \"\"\n },\n /**\n * Id for the `` element\n */\n anchorId: {\n type: String,\n default: \"\"\n },\n /**\n * Make subname bold\n */\n bold: {\n type: Boolean,\n default: !1\n },\n /**\n * Show the NcListItem in compact design\n */\n compact: {\n type: Boolean,\n default: !1\n },\n /**\n * Toggle the active state of the component\n */\n active: {\n type: Boolean,\n default: !1\n },\n /**\n * Aria label for the wrapper element\n */\n linkAriaLabel: {\n type: String,\n default: \"\"\n },\n /**\n * Aria label for the actions toggle\n */\n actionsAriaLabel: {\n type: String,\n default: \"\"\n },\n /**\n * If different from 0 this component will display the\n * NcCounterBubble component\n */\n counterNumber: {\n type: [Number, String],\n default: 0\n },\n /**\n * Outlined or highlighted state of the counter\n */\n counterType: {\n type: String,\n default: \"\",\n validator(s) {\n return [\"highlighted\", \"outlined\", \"\"].indexOf(s) !== -1;\n }\n },\n /**\n * To be used only when the elements in the actions menu are very important\n */\n forceDisplayActions: {\n type: Boolean,\n default: !1\n },\n /**\n * Show the list component layout\n */\n oneLine: {\n type: Boolean,\n default: !1\n }\n },\n emits: [\n \"click\",\n \"update:menuOpen\"\n ],\n data() {\n return {\n hovered: !1,\n hasActions: !1,\n hasSubname: !1,\n displayActionsOnHoverFocus: !1,\n menuOpen: !1,\n hasIndicator: !1,\n hasDetails: !1\n };\n },\n computed: {\n showAdditionalElements() {\n return !this.displayActionsOnHoverFocus || this.forceDisplayActions;\n },\n showDetails() {\n return (this.details !== \"\" || this.hasDetails) && (!this.displayActionsOnHoverFocus || this.forceDisplayActions);\n },\n computedActionsAriaLabel() {\n return this.actionsAriaLabel || h('Actions for item with name \"{name}\"', { name: this.name });\n }\n },\n watch: {\n menuOpen(s) {\n !s && !this.hovered && (this.displayActionsOnHoverFocus = !1);\n }\n },\n mounted() {\n this.checkSlots();\n },\n updated() {\n this.checkSlots();\n },\n methods: {\n /**\n * Handle link click\n *\n * @param {MouseEvent|KeyboardEvent} event - Native click or keydown event\n * @param {Function} [navigate] - VueRouter link's navigate if any\n * @param {string} [routerLinkHref] - VueRouter link's href\n */\n onClick(s, t, e) {\n this.$emit(\"click\", s), !(s.metaKey || s.altKey || s.ctrlKey || s.shiftKey) && e && (t == null || t(s), s.preventDefault());\n },\n showActions() {\n this.hasActions && (this.displayActionsOnHoverFocus = !0), this.hovered = !1;\n },\n hideActions() {\n this.displayActionsOnHoverFocus = !1;\n },\n /**\n * @param {FocusEvent} event UI event\n */\n handleBlur(s) {\n this.menuOpen || this.$refs[\"list-item\"].contains(s.relatedTarget) || this.hideActions();\n },\n /**\n * Hide the actions on mouseleave unless the menu is open\n */\n handleMouseleave() {\n this.menuOpen || (this.displayActionsOnHoverFocus = !1), this.hovered = !1;\n },\n handleMouseover() {\n this.showActions(), this.hovered = !0;\n },\n handleActionsUpdateOpen(s) {\n this.menuOpen = s, this.$emit(\"update:menuOpen\", s);\n },\n // Check if subname and actions slots are populated\n checkSlots() {\n this.hasActions !== !!this.$slots.actions && (this.hasActions = !!this.$slots.actions), this.hasSubname !== !!this.$slots.subname && (this.hasSubname = !!this.$slots.subname), this.hasIndicator !== !!this.$slots.indicator && (this.hasIndicator = !!this.$slots.indicator), this.hasDetails !== !!this.$slots.details && (this.hasDetails = !!this.$slots.details);\n }\n }\n};\nvar p = function() {\n var t = this, e = t._self._c;\n return e(t.to ? \"router-link\" : \"NcVNodes\", { tag: \"component\", attrs: { custom: t.to ? !0 : null, to: t.to, exact: t.to ? t.exact : null }, scopedSlots: t._u([{ key: \"default\", fn: function({ href: n, navigate: o, isActive: a }) {\n return [e(\"li\", { staticClass: \"list-item__wrapper\", class: { \"list-item__wrapper--active\": a || t.active } }, [e(\"div\", { ref: \"list-item\", staticClass: \"list-item\", class: {\n \"list-item--compact\": t.compact,\n \"list-item--one-line\": t.oneLine\n }, on: { mouseover: t.handleMouseover, mouseleave: t.handleMouseleave } }, [e(\"a\", { staticClass: \"list-item__anchor\", attrs: { id: t.anchorId || void 0, \"aria-label\": t.linkAriaLabel, href: n || t.href, target: t.target || (t.href === \"#\" ? void 0 : \"_blank\"), rel: t.href === \"#\" ? void 0 : \"noopener noreferrer\" }, on: { focus: t.showActions, focusout: t.handleBlur, click: function(i) {\n return t.onClick(i, o, n);\n }, keydown: function(i) {\n return !i.type.indexOf(\"key\") && t._k(i.keyCode, \"esc\", 27, i.key, [\"Esc\", \"Escape\"]) ? null : t.hideActions.apply(null, arguments);\n } } }, [t._t(\"icon\"), e(\"div\", { staticClass: \"list-item-content\" }, [e(\"div\", { staticClass: \"list-item-content__main\" }, [e(\"div\", { staticClass: \"list-item-content__name\" }, [t._v(\" \" + t._s(t.name) + \" \")]), t.hasSubname ? e(\"div\", { staticClass: \"list-item-content__subname\", class: { \"line-two--bold\": t.bold } }, [t._t(\"subname\")], 2) : t._e()]), e(\"div\", { staticClass: \"list-item-content__details\" }, [t.showDetails ? e(\"div\", { staticClass: \"list-item-details__details\" }, [t._t(\"details\", function() {\n return [t._v(t._s(t.details))];\n })], 2) : t._e(), t.counterNumber != 0 || t.hasIndicator ? e(\"div\", { directives: [{ name: \"show\", rawName: \"v-show\", value: t.showAdditionalElements, expression: \"showAdditionalElements\" }], staticClass: \"list-item-details__extra\" }, [t.counterNumber != 0 ? e(\"NcCounterBubble\", { staticClass: \"list-item-details__counter\", attrs: { active: a || t.active, type: t.counterType } }, [t._v(\" \" + t._s(t.counterNumber) + \" \")]) : t._e(), t.hasIndicator ? e(\"span\", { staticClass: \"list-item-details__indicator\" }, [t._t(\"indicator\")], 2) : t._e()], 1) : t._e()])])], 2), e(\"div\", { directives: [{ name: \"show\", rawName: \"v-show\", value: t.forceDisplayActions || t.displayActionsOnHoverFocus, expression: \"forceDisplayActions || displayActionsOnHoverFocus\" }], staticClass: \"list-item-content__actions\", on: { focusout: t.handleBlur } }, [e(\"NcActions\", { ref: \"actions\", attrs: { primary: a || t.active, \"aria-label\": t.computedActionsAriaLabel }, on: { \"update:open\": t.handleActionsUpdateOpen } }, [t._t(\"actions\")], 2)], 1), t.$slots.extra ? e(\"div\", { staticClass: \"list-item__extra\" }, [t._t(\"extra\")], 2) : t._e()])])];\n } }], null, !0) });\n}, _ = [], y = /* @__PURE__ */ m(\n f,\n p,\n _,\n !1,\n null,\n \"2318213f\",\n null,\n null\n);\nconst C = y.exports;\nexport {\n C as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcListItemIcon-9Dazpmpd.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcListItemIcon-9Dazpmpd.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcMentionBubble-BhiXWJv8.css';\nimport '../assets/NcListItemIcon-9Dazpmpd.css';\nimport { N as i, u as r } from \"./NcAvatar-BdtXzaRJ.mjs\";\nimport { N as n } from \"./index-CnpswYi6.mjs\";\nimport { N as o } from \"./NcIconSvgWrapper-BTdzvQGV.mjs\";\nimport \"../Composables/useIsFullscreen.mjs\";\nimport \"../Composables/useIsMobile.mjs\";\nimport \"@nextcloud/router\";\n/* empty css */\nimport { n as c } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nimport \"linkify-string\";\nimport \"escape-html\";\nimport \"striptags\";\nimport \"vue\";\nconst l = 8, e = 32, u = {\n name: \"NcListItemIcon\",\n components: {\n NcAvatar: i,\n NcHighlight: n,\n NcIconSvgWrapper: o\n },\n mixins: [\n r\n ],\n props: {\n /**\n * Default first line text\n */\n name: {\n type: String,\n required: !0\n },\n /**\n * Secondary optional line\n * Only visible on size of 32 and above\n */\n subname: {\n type: String,\n default: \"\"\n },\n /**\n * Icon class to be displayed at the end of the component\n */\n icon: {\n type: String,\n default: \"\"\n },\n /**\n * SVG icon to be displayed at the end of the component\n */\n iconSvg: {\n type: String,\n default: \"\"\n },\n /**\n * Descriptive name for the icon\n */\n iconName: {\n type: String,\n default: \"\"\n },\n /**\n * Search within the highlight of name/subname\n */\n search: {\n type: String,\n default: \"\"\n },\n /**\n * Set a size in px that will define the avatar height/width\n * and therefore, the height of the component\n */\n avatarSize: {\n type: Number,\n default: e\n },\n /**\n * Disable the margins of this component.\n * Useful for integration in `NcSelect` for example\n */\n noMargin: {\n type: Boolean,\n default: !1\n },\n /**\n * See the [Avatar](#Avatar) displayName prop\n * Fallback to name\n */\n displayName: {\n type: String,\n default: null\n },\n /**\n * See the [Avatar](#Avatar) isNoUser prop\n * Enable/disable the UserStatus fetching\n */\n isNoUser: {\n type: Boolean,\n default: !1\n },\n /**\n * Unique list item ID\n */\n id: {\n type: String,\n default: null\n }\n },\n data() {\n return {\n margin: l\n };\n },\n computed: {\n hasIcon() {\n return this.icon !== \"\";\n },\n hasIconSvg() {\n return this.iconSvg !== \"\";\n },\n isValidSubname() {\n var a, t;\n return ((t = (a = this.subname) == null ? void 0 : a.trim) == null ? void 0 : t.call(a)) !== \"\";\n },\n isSizeBigEnough() {\n return this.avatarSize >= e;\n },\n cssVars() {\n const a = this.noMargin ? 0 : this.margin;\n return {\n \"--height\": this.avatarSize + 2 * a + \"px\",\n \"--margin\": this.margin + \"px\"\n };\n },\n /**\n * Seperates the search property into two parts, the first one is the search part on the name, the second on the subname.\n * @return {[string, string]}\n */\n searchParts() {\n const a = /^([^<]*)<([^>]+)>?$/, t = this.search.match(a);\n return this.isNoUser || !t ? [this.search, this.search] : [t[1].trim(), t[2]];\n }\n },\n beforeMount() {\n !this.isNoUser && !this.subname && this.fetchUserStatus(this.user);\n }\n};\nvar m = function() {\n var t = this, s = t._self._c;\n return s(\"span\", t._g({ staticClass: \"option\", style: t.cssVars, attrs: { id: t.id } }, t.$listeners), [s(\"NcAvatar\", t._b({ staticClass: \"option__avatar\", attrs: { \"disable-menu\": !0, \"disable-tooltip\": !0, \"display-name\": t.displayName || t.name, \"is-no-user\": t.isNoUser, size: t.avatarSize } }, \"NcAvatar\", t.$attrs, !1)), s(\"div\", { staticClass: \"option__details\" }, [s(\"NcHighlight\", { staticClass: \"option__lineone\", attrs: { text: t.name, search: t.searchParts[0] } }), t.isValidSubname && t.isSizeBigEnough ? s(\"NcHighlight\", { staticClass: \"option__linetwo\", attrs: { text: t.subname, search: t.searchParts[1] } }) : t.hasStatus ? s(\"span\", [s(\"span\", [t._v(t._s(t.userStatus.icon))]), s(\"span\", [t._v(t._s(t.userStatus.message))])]) : t._e()], 1), t._t(\"default\", function() {\n return [t.hasIconSvg ? s(\"NcIconSvgWrapper\", { staticClass: \"option__icon\", attrs: { svg: t.iconSvg, name: t.iconName } }) : t.hasIcon ? s(\"span\", { staticClass: \"icon option__icon\", class: t.icon, attrs: { \"aria-label\": t.iconName } }) : t._e()];\n })], 2);\n}, p = [], h = /* @__PURE__ */ c(\n u,\n m,\n p,\n !1,\n null,\n \"562c32c6\",\n null,\n null\n);\nconst x = h.exports;\nexport {\n x as N\n};\n","import { n as l } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nimport a from \"../Components/NcInputField.mjs\";\nimport o from \"debounce\";\nimport c from \"@nextcloud/axios\";\nimport { loadState as d } from \"@nextcloud/initial-state\";\nimport { generateOcsUrl as u } from \"@nextcloud/router\";\nimport { r as p, q as f, a as n } from \"./_l10n-CAwwH-o2.mjs\";\nimport { l as m } from \"./logger-C7qcfVW8.mjs\";\nconst h = {\n name: \"EyeIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar _ = function() {\n var t = this, s = t._self._c;\n return s(\"span\", t._b({ staticClass: \"material-design-icon eye-icon\", attrs: { \"aria-hidden\": t.title ? null : !0, \"aria-label\": t.title, role: \"img\" }, on: { click: function(i) {\n return t.$emit(\"click\", i);\n } } }, \"span\", t.$attrs, !1), [s(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { fill: t.fillColor, width: t.size, height: t.size, viewBox: \"0 0 24 24\" } }, [s(\"path\", { attrs: { d: \"M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z\" } }, [t.title ? s(\"title\", [t._v(t._s(t.title))]) : t._e()])])]);\n}, g = [], v = /* @__PURE__ */ l(\n h,\n _,\n g,\n !1,\n null,\n null,\n null,\n null\n);\nconst w = v.exports, C = {\n name: \"EyeOffIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar y = function() {\n var t = this, s = t._self._c;\n return s(\"span\", t._b({ staticClass: \"material-design-icon eye-off-icon\", attrs: { \"aria-hidden\": t.title ? null : !0, \"aria-label\": t.title, role: \"img\" }, on: { click: function(i) {\n return t.$emit(\"click\", i);\n } } }, \"span\", t.$attrs, !1), [s(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { fill: t.fillColor, width: t.size, height: t.size, viewBox: \"0 0 24 24\" } }, [s(\"path\", { attrs: { d: \"M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z\" } }, [t.title ? s(\"title\", [t._v(t._s(t.title))]) : t._e()])])]);\n}, b = [], $ = /* @__PURE__ */ l(\n C,\n y,\n b,\n !1,\n null,\n null,\n null,\n null\n);\nconst P = $.exports;\np(f);\nconst r = d(\"core\", \"capabilities\", {}).password_policy || null, A = new Set(Object.keys(a.props)), x = {\n name: \"NcPasswordField\",\n components: {\n NcInputField: a,\n Eye: w,\n EyeOff: P\n },\n // Allow forwarding all attributes\n inheritAttrs: !1,\n props: {\n /**\n * Any [NcInputField](#/Components/NcFields?id=ncinputfield) props\n */\n // Not an actual prop but needed to show in vue-styleguidist docs\n // eslint-disable-next-line\n \" \": {},\n // Reuse all the props from NcInputField for better typing and documentation\n ...a.props,\n // Redefined props\n /**\n * Controls whether to display the trailing button.\n */\n showTrailingButton: {\n type: Boolean,\n default: !0\n },\n // Removed NcInputField props, defined only by this component\n trailingButtonLabel: void 0,\n // Custom props\n /**\n * Check if the user entered a valid password using the password_policy\n * app if available.\n *\n * Warning: this doesn't replace server side checking and will do nothing\n * if the password_policy app is disabled.\n */\n checkPasswordStrength: {\n type: Boolean,\n default: !1\n },\n /**\n * The minlength property defines the minimum number of characters\n * (as UTF-16 code units) the user can enter\n */\n minlength: {\n type: Number,\n default: 0\n },\n /**\n * The maxlength property defines the maximum number of characters\n * (as UTF-16 code units) the user can enter\n */\n maxlength: {\n type: Number,\n default: null\n }\n },\n emits: [\n \"valid\",\n \"invalid\",\n \"update:value\"\n ],\n data() {\n return {\n isPasswordHidden: !0,\n internalHelpMessage: \"\",\n isValid: null\n };\n },\n computed: {\n computedError() {\n return this.error || this.isValid === !1;\n },\n computedSuccess() {\n return this.success || this.isValid === !0;\n },\n computedHelperText() {\n return this.helperText.length > 0 ? this.helperText : this.internalHelpMessage;\n },\n rules() {\n const { minlength: e } = this;\n return {\n minlength: e != null ? e : r == null ? void 0 : r.minLength\n };\n },\n trailingButtonLabelPassword() {\n return this.isPasswordHidden ? n(\"Show password\") : n(\"Hide password\");\n },\n propsAndAttrsToForward() {\n return {\n // Proxy all the HTML attributes\n ...this.$attrs,\n // Proxy original NcInputField's props\n ...Object.fromEntries(\n Object.entries(this.$props).filter(([e]) => A.has(e))\n )\n };\n }\n },\n watch: {\n value(e) {\n if (this.checkPasswordStrength) {\n if (r === null)\n return;\n this.checkPassword(e);\n }\n }\n },\n methods: {\n /**\n * Focus the input element\n *\n * @public\n */\n focus() {\n this.$refs.inputField.focus();\n },\n /**\n * Select all the text in the input\n *\n * @public\n */\n select() {\n this.$refs.inputField.select();\n },\n handleInput(e) {\n this.$emit(\"update:value\", e.target.value);\n },\n togglePasswordVisibility() {\n this.isPasswordHidden = !this.isPasswordHidden;\n },\n checkPassword: o(async function(e) {\n try {\n const { data: t } = await c.post(u(\"apps/password_policy/api/v1/validate\"), { password: e });\n if (this.isValid = t.ocs.data.passed, t.ocs.data.passed) {\n this.internalHelpMessage = n(\"Password is secure\"), this.$emit(\"valid\");\n return;\n }\n this.internalHelpMessage = t.ocs.data.reason, this.$emit(\"invalid\");\n } catch (t) {\n m.error(\"Password policy returned an error\", t);\n }\n }, 500)\n }\n};\nvar L = function() {\n var t = this, s = t._self._c;\n return s(\"NcInputField\", t._g(t._b({ ref: \"inputField\", attrs: { type: t.isPasswordHidden ? \"password\" : \"text\", \"trailing-button-label\": t.trailingButtonLabelPassword, \"helper-text\": t.computedHelperText, error: t.computedError, success: t.computedSuccess, minlength: t.rules.minlength }, on: { \"trailing-button-click\": t.togglePasswordVisibility, input: t.handleInput }, scopedSlots: t._u([{ key: \"trailing-button-icon\", fn: function() {\n return [t.isPasswordHidden ? s(\"Eye\", { attrs: { size: 18 } }) : s(\"EyeOff\", { attrs: { size: 18 } })];\n }, proxy: !0 }]) }, \"NcInputField\", t.propsAndAttrsToForward, !1), t.$listeners), [t._t(\"default\")], 2);\n}, F = [], k = /* @__PURE__ */ l(\n x,\n L,\n F,\n !1,\n null,\n null,\n null,\n null\n);\nconst O = k.exports;\nexport {\n O as N\n};\n","\n import API from \"!../../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../css-loader/dist/cjs.js!./NcPopover-wrgZy49g.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../css-loader/dist/cjs.js!./NcPopover-wrgZy49g.css\";\n export default content && content.locals ? content.locals : undefined;\n","import '../assets/NcPopover-wrgZy49g.css';\nimport s, { defineComponent as a } from \"vue\";\nimport { Dropdown as i } from \"floating-vue\";\nimport { createFocusTrap as p } from \"focus-trap\";\nimport { g as u } from \"./focusTrap-Be9GEB5C.mjs\";\nimport { n } from \"./_plugin-vue2_normalizer-Bj5bLKV4.mjs\";\nconst l = a({\n name: \"NcPopoverTriggerProvider\",\n provide() {\n return {\n \"NcPopover:trigger:shown\": () => this.shown,\n \"NcPopover:trigger:attrs\": () => this.triggerAttrs\n };\n },\n props: {\n shown: {\n type: Boolean,\n required: !0\n },\n popupRole: {\n type: String,\n default: void 0\n }\n },\n computed: {\n triggerAttrs() {\n return {\n \"aria-haspopup\": this.popupRole,\n \"aria-expanded\": this.shown.toString()\n };\n }\n },\n render() {\n var e, t;\n return (t = (e = this.$scopedSlots).default) == null ? void 0 : t.call(e, {\n attrs: this.triggerAttrs\n });\n }\n}), c = null, d = null;\nvar g = /* @__PURE__ */ n(\n l,\n c,\n d,\n !1,\n null,\n null,\n null,\n null\n);\nconst h = g.exports, f = {\n name: \"NcPopover\",\n components: {\n Dropdown: i,\n NcPopoverTriggerProvider: h\n },\n inheritAttrs: !1,\n props: {\n /**\n * Show or hide the popper\n * @see https://floating-vue.starpad.dev/api/#shown\n */\n shown: {\n type: Boolean,\n default: !1\n },\n /**\n * Popup role\n * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-haspopup#values\n */\n popupRole: {\n type: String,\n default: void 0,\n validator: (e) => [\"menu\", \"listbox\", \"tree\", \"grid\", \"dialog\", \"true\"].includes(e)\n },\n popoverBaseClass: {\n type: String,\n default: \"\"\n },\n /**\n * Enable popover focus trap\n */\n focusTrap: {\n type: Boolean,\n default: !0\n },\n /**\n * Set element to return focus to after focus trap deactivation\n *\n * @type {import('focus-trap').FocusTargetValueOrFalse}\n */\n setReturnFocus: {\n default: void 0,\n type: [HTMLElement, SVGElement, String, Boolean]\n }\n },\n emits: [\n \"after-show\",\n \"after-hide\",\n /**\n * @see https://floating-vue.starpad.dev/api/#update-shown\n */\n \"update:shown\"\n ],\n data() {\n return {\n internalShown: this.shown\n };\n },\n watch: {\n shown(e) {\n this.internalShown = e;\n },\n internalShown(e) {\n this.$emit(\"update:shown\", e);\n }\n },\n mounted() {\n this.checkTriggerA11y();\n },\n beforeDestroy() {\n this.clearFocusTrap(), this.clearEscapeStopPropagation();\n },\n methods: {\n /**\n * Check if the trigger has all required a11y attributes.\n * Important to check custom trigger button.\n */\n checkTriggerA11y() {\n var e;\n (e = window.OC) != null && e.debug && (this.getPopoverTriggerContainerElement().querySelector(\"[aria-expanded]\") || s.util.warn(\"It looks like you are using a custom button as a or other popover #trigger. If you are not using as a trigger, you need to bind attrs from the #trigger slot props to your custom button. See docs for an example.\"));\n },\n /**\n * Remove incorrect aria-describedby attribute from the trigger.\n * @see https://github.com/Akryum/floating-vue/blob/8d4f7125aae0e3ea00ba4093d6d2001ab15058f1/packages/floating-vue/src/components/Popper.ts#L734\n */\n removeFloatingVueAriaDescribedBy() {\n const t = this.getPopoverTriggerContainerElement().querySelectorAll(\"[data-popper-shown]\");\n for (const r of t)\n r.removeAttribute(\"aria-describedby\");\n },\n /**\n * @return {HTMLElement|undefined}\n */\n getPopoverContentElement() {\n var e, t;\n return (t = (e = this.$refs.popover) == null ? void 0 : e.$refs.popperContent) == null ? void 0 : t.$el;\n },\n /**\n * @return {HTMLElement|undefined}\n */\n getPopoverTriggerContainerElement() {\n return this.$refs.popover.$refs.reference;\n },\n /**\n * Add focus trap for accessibility.\n */\n async useFocusTrap() {\n if (await this.$nextTick(), !this.focusTrap)\n return;\n const e = this.getPopoverContentElement();\n e && (this.$focusTrap = p(e, {\n // Prevents to lose focus using esc key\n // Focus will be release when popover be hide\n escapeDeactivates: !1,\n allowOutsideClick: !0,\n setReturnFocus: this.setReturnFocus,\n trapStack: u()\n }), this.$focusTrap.activate());\n },\n /**\n * Remove focus trap\n *\n * @param {object} options The configuration options for focusTrap\n */\n clearFocusTrap(e = {}) {\n var t;\n try {\n (t = this.$focusTrap) == null || t.deactivate(e), this.$focusTrap = null;\n } catch (r) {\n console.warn(r);\n }\n },\n /**\n * Add stopPropagation for Escape.\n * It prevents global Escape handling after closing popover.\n *\n * Manual event handling is used here instead of v-on because there is no direct access to the node.\n * Alternative - wrap