@nextcloud/vue
Version:
Nextcloud vue components
889 lines (888 loc) • 30.3 kB
JavaScript
require('../assets/NcActions-CkVHYk_-.css');
"use strict";
const Components_NcButton = require("../Components/NcButton.cjs");
const NcPopover = require("./NcPopover-C0G7sLVP.cjs");
const GenRandomId = require("./GenRandomId-BQDud3d4.cjs");
const _l10n = require("./_l10n-Ci9_UR5q.cjs");
const focusTrap = require("./focusTrap-EeXFmjdI.cjs");
const core = require("@vueuse/core");
const Vue = require("vue");
const DotsHorizontal = require("./DotsHorizontal-DQfnwpao.cjs");
const _pluginVue2_normalizer = require("./_plugin-vue2_normalizer-V0q-tHlQ.cjs");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const Vue__default = /* @__PURE__ */ _interopDefault(Vue);
_l10n.register(_l10n.t4);
const focusableSelector = ".focusable";
const _sfc_main = {
name: "NcActions",
components: {
NcButton: Components_NcButton,
NcPopover: NcPopover.NcPopover
},
provide() {
return {
/**
* NcActions can be used as:
* - Application menu (has menu role)
* - Expanded block (has no specific role, should be used an element with expanded role)
* - Popover with plain text or text inputs (has no specific role)
* Depending on the usage (used items), the menu and its items should have different roles for a11y.
* Provide the role for NcAction* components in the NcActions content.
* @type {import('vue').ComputedRef<boolean>}
*/
"NcActions:isSemanticMenu": Vue.computed(() => this.actionsMenuSemanticType === "menu")
};
},
props: {
/**
* Specify the open state of the popover menu
*/
open: {
type: Boolean,
default: false
},
/**
* This disables the internal open management,
* so the actions menu only respects the `open` prop.
* This is e.g. necessary for the NcAvatar component
* to only open the actions menu after loading it's entries has finished.
*/
manualOpen: {
type: Boolean,
default: false
},
/**
* Force the actions to display in a three dot menu
*/
forceMenu: {
type: Boolean,
default: false
},
/**
* Force the name to show for single actions
*/
forceName: {
type: Boolean,
default: false
},
/**
* Specify the menu name
*/
menuName: {
type: String,
default: null
},
/**
* NcActions can be used as:
*
* - Application menu (has menu role)
* - Navigation (has no specific role, should be used an element with expanded role)
* - Popover with plain text or text inputs (has no specific role)
*
* By default the used type is automatically detected by components used in the default slot.#
*
* With Vue this is limited to direct children of the NcActions component.
* So if you use a wrapper, you have to provide the semantic type yourself (see Example)
*
* Choose:
*
* - 'dialog' if you use any of these components: NcActionInput', 'NcActionTextEditable'
* - 'menu' if you use any of these components: 'NcActionButton', 'NcActionButtonGroup', 'NcActionCheckbox', 'NcActionRadio'
* - 'expanded' if using one of these: 'NcActionLink', 'NcActionRouter'. This represents an expanded block.
* - 'tooltip' only to be used when a text without any interactive elements is used.
* - Leave this property unset otherwise
*/
forceSemanticType: {
type: String,
default: null,
validator(value) {
return ["dialog", "menu", "expanded", "tooltip"].includes(value);
}
},
/**
* Apply primary styling for this menu
*/
primary: {
type: Boolean,
default: false
},
/**
* Specifies the button type used for trigger and single actions buttons
* Accepted values: primary, secondary, tertiary, tertiary-no-background, tertiary-on-primary, error, warning, success. If left empty,
* the default button style will be applied.
*/
type: {
type: String,
validator(value) {
return ["primary", "secondary", "tertiary", "tertiary-no-background", "tertiary-on-primary", "error", "warning", "success"].indexOf(value) !== -1;
},
default: null
},
/**
* Icon to show for the toggle menu button
* when more than one action is inside the actions component.
* Only replace the default three-dot icon if really necessary.
*/
defaultIcon: {
type: String,
default: ""
},
/**
* Aria label for the actions menu.
*
* If `menuName` is defined this will not be used to prevent
* any accessible name conflicts. This ensures that the
* element can be activated via voice input.
*/
ariaLabel: {
type: String,
default: _l10n.t("Actions")
},
/**
* @deprecated To be removed in @nextcloud/vue 9. Migration guide: remove ariaHidden prop from NcAction* components.
* @todo Add a check in @nextcloud/vue 9 that this prop is not provided,
* otherwise root element will inherit incorrect aria-hidden.
*/
ariaHidden: {
type: Boolean,
default: null
},
/**
* Wanted direction of the menu
*/
placement: {
type: String,
default: "bottom"
},
/**
* DOM element for the actions' popover boundaries
*/
boundariesElement: {
type: Element,
default: () => {
var _a;
return (_a = document.querySelector("#content-vue")) != null ? _a : document.querySelector("body");
}
},
/**
* Selector for the actions' popover container
*/
container: {
type: [String, Object, Element, Boolean],
default: "body"
},
/**
* Disabled state of the main button (single action or menu toggle)
*/
disabled: {
type: Boolean,
default: false
},
/**
* Display x items inline out of the dropdown menu
* Will be ignored if `forceMenu` is set
*/
inline: {
type: Number,
default: 0
}
},
emits: [
"open",
"update:open",
"close",
"focus",
"blur",
"click"
],
setup(props) {
const randomId = "menu-".concat(GenRandomId.GenRandomId());
const triggerRandomId = "trigger-".concat(randomId);
const triggerButton = Vue.ref();
const { top, bottom } = core.useElementBounding(triggerButton);
const { top: boundaryTop, bottom: boundaryBottom } = core.useElementBounding(Vue.toRef(props, "boundariesElement"));
const { height: windowHeight } = core.useWindowSize();
const maxMenuHeight = Vue.computed(() => Math.max(
// Either expand to the top
Math.min(
// max height is the top position of the trigger minus the header height minus the wedge and the padding
top.value - 84,
// and also limited to the space in the boundary
top.value - boundaryTop.value
),
// or expand to the bottom
Math.min(
// the max height is the window height minus current position of the trigger minus the wedge and padding
windowHeight.value - bottom.value - 34,
// and limit to the available space in the boundary
boundaryBottom.value - bottom.value
)
));
return {
triggerButton,
maxMenuHeight,
randomId,
triggerRandomId
};
},
data() {
return {
opened: this.open,
focusIndex: 0,
/**
* @type {'menu'|'expanded'|'dialog'|'tooltip'|'unknown'}
*/
actionsMenuSemanticType: "unknown",
externalFocusTrapStack: []
};
},
computed: {
triggerBtnType() {
return this.type || (this.primary ? "primary" : this.menuName ? "secondary" : "tertiary");
},
/**
* A11y roles and keyboard navigation configuration depending on the semantic type
*/
config() {
const configs = {
menu: {
popupRole: "menu",
withArrowNavigation: true,
withTabNavigation: false,
withFocusTrap: false,
triggerA11yAttr: {
"aria-controls": this.opened ? this.randomId : null
},
popoverContainerA11yAttrs: {},
popoverUlA11yAttrs: {
"aria-labelledby": this.triggerRandomId,
id: this.randomId,
role: "menu"
}
},
expanded: {
popupRole: void 0,
withArrowNavigation: false,
withTabNavigation: true,
withFocusTrap: false,
triggerA11yAttr: {},
popoverContainerA11yAttrs: {},
popoverUlA11yAttrs: {}
},
dialog: {
popupRole: "dialog",
withArrowNavigation: false,
withTabNavigation: true,
withFocusTrap: true,
triggerA11yAttr: {
"aria-controls": this.opened ? this.randomId : null
},
popoverContainerA11yAttrs: {
id: this.randomId,
role: "dialog",
// Dialog must have a label
"aria-labelledby": this.triggerRandomId,
"aria-modal": "true"
},
popoverUlA11yAttrs: {}
},
tooltip: {
popupRole: void 0,
withArrowNavigation: false,
withTabNavigation: false,
withFocusTrap: false,
triggerA11yAttr: {},
popoverContainerA11yAttrs: {},
popoverUlA11yAttrs: {}
},
// Due to Vue limitations, we sometimes cannot determine the true type
// As a fallback use both arrow navigation and focus trap
unknown: {
popupRole: void 0,
role: void 0,
withArrowNavigation: true,
withTabNavigation: false,
withFocusTrap: true,
triggerA11yAttr: {},
popoverContainerA11yAttrs: {},
popoverUlA11yAttrs: {
// there is nothing against labelling a list, it is mostly recommended
// so as we do not know the dialog type lets include the label
"aria-labelledby": this.triggerRandomId
}
}
};
return configs[this.actionsMenuSemanticType];
}
},
watch: {
// Watch parent prop
open(state) {
if (state === this.opened) {
return;
}
this.opened = state;
},
opened() {
this.intersectIntoCurrentFocusTrapStack();
if (this.opened) {
document.body.addEventListener("keydown", this.handleEscapePressed);
} else {
document.body.removeEventListener("keydown", this.handleEscapePressed);
}
}
},
methods: {
/**
* Get the name of the action component
*
* @param {import('vue').VNode} action - a vnode with a NcAction* component instance
* @return {string} the name of the action component
*/
getActionName(action) {
var _a, _b, _c, _d, _e;
return (_e = (_c = (_b = (_a = action == null ? void 0 : action.componentOptions) == null ? void 0 : _a.Ctor) == null ? void 0 : _b.extendOptions) == null ? void 0 : _c.name) != null ? _e : (_d = action == null ? void 0 : action.componentOptions) == null ? void 0 : _d.tag;
},
/**
* When the component has its own focus trap, then it is managed by global trap stack by focus-trap.
*
* However if the component has no focus trap and is used inside another focus trap - there is an issue.
* By default popover content is rendered in body or other container, which is likely outside the current focus trap containers.
* It results in broken behavior from focus-trap.
*
* We need to pause all the focus traps for opening popover and then unpause them back after closing.
*/
intersectIntoCurrentFocusTrapStack() {
if (this.config.withFocusTrap) {
return;
}
if (this.opened) {
this.externalFocusTrapStack = [...focusTrap.getTrapStack()];
for (const trap of this.externalFocusTrapStack) {
trap.pause();
}
} else {
for (const trap of this.externalFocusTrapStack) {
trap.unpause();
}
this.externalFocusTrapStack = [];
}
},
/**
* Do we have exactly one Action and
* is it allowed as a standalone element?
*
* @param {import('vue').VNode} action The action to check
* @return {boolean}
*/
isValidSingleAction(action) {
return ["NcActionButton", "NcActionLink", "NcActionRouter"].includes(this.getActionName(action));
},
/**
* Check whether a icon prop value is an URL or not
* @param {string} url The icon prop value
*/
isIconUrl(url) {
try {
return !!new URL(url, url.startsWith("/") ? window.location.origin : void 0);
} catch (error) {
return false;
}
},
// MENU STATE MANAGEMENT
openMenu(e) {
if (this.opened) {
return;
}
this.opened = true;
this.$emit("update:open", true);
this.$emit("open");
},
async closeMenu(returnFocus = true) {
var _a, _b;
if (!this.opened) {
return;
}
await this.$nextTick();
this.opened = false;
(_a = this.$refs.popover) == null ? void 0 : _a.clearFocusTrap({ returnFocus });
this.$emit("update:open", false);
this.$emit("close");
this.focusIndex = 0;
if (returnFocus) {
(_b = this.$refs.triggerButton) == null ? void 0 : _b.$el.focus();
}
},
onClosed() {
this.$emit("closed");
},
/**
* Called when popover is shown after the show delay
*/
onOpen() {
this.$nextTick(() => {
this.focusFirstAction(null);
this.resizePopover();
});
},
/**
* Handle resizing the popover to make sure users can discover there is more to scroll
*/
resizePopover() {
const inner = this.$refs.menu.closest(".v-popper__inner");
const height = this.$refs.menu.clientHeight;
if (height > this.maxMenuHeight) {
let currentHeight = 0;
let actionHeight = 0;
for (const action of this.$refs.menuList.children) {
if (currentHeight + action.clientHeight / 2 > this.maxMenuHeight) {
inner.style.height = "".concat(currentHeight - actionHeight / 2, "px");
break;
}
actionHeight = action.clientHeight;
currentHeight += actionHeight;
}
} else {
inner.style.height = "fit-content";
}
},
// MENU KEYS & FOCUS MANAGEMENT
/**
* @return {HTMLElement|null}
*/
getCurrentActiveMenuItemElement() {
return this.$refs.menu.querySelector("li.active");
},
/**
* @return {NodeListOf<HTMLElement>}
*/
getFocusableMenuItemElements() {
return this.$refs.menu.querySelectorAll(focusableSelector);
},
/**
* Focus nearest focusable item on mouse move.
* DO NOT change the focus if the target is already focused
* this will prevent issues with input being unfocused
* on mouse move
* @param {PointerEvent} event - The mouse move event
*/
onMouseFocusAction(event) {
if (document.activeElement === event.target) {
return;
}
const menuItem = event.target.closest("li");
if (menuItem && this.$refs.menu.contains(menuItem)) {
const focusableItem = menuItem.querySelector(focusableSelector);
if (focusableItem) {
const focusList = this.getFocusableMenuItemElements();
const focusIndex = [...focusList].indexOf(focusableItem);
if (focusIndex > -1) {
this.focusIndex = focusIndex;
this.focusAction();
}
}
}
},
/**
* Dispatches the keydown listener to different handlers
*
* @param {object} event The keydown event
*/
onKeydown(event) {
if (event.key === "Tab") {
if (this.config.withFocusTrap) {
return;
}
if (!this.config.withTabNavigation) {
this.closeMenu(true);
return;
}
event.preventDefault();
const focusList = this.getFocusableMenuItemElements();
const focusIndex = [...focusList].indexOf(document.activeElement);
if (focusIndex === -1) {
return;
}
const newFocusIndex = event.shiftKey ? focusIndex - 1 : focusIndex + 1;
if (newFocusIndex < 0 || newFocusIndex === focusList.length) {
this.closeMenu(true);
}
this.focusIndex = newFocusIndex;
this.focusAction();
return;
}
if (this.config.withArrowNavigation) {
if (event.key === "ArrowUp") {
this.focusPreviousAction(event);
}
if (event.key === "ArrowDown") {
this.focusNextAction(event);
}
if (event.key === "PageUp") {
this.focusFirstAction(event);
}
if (event.key === "PageDown") {
this.focusLastAction(event);
}
}
this.handleEscapePressed(event);
},
onTriggerKeydown(event) {
if (event.key === "Escape") {
if (this.actionsMenuSemanticType === "tooltip") {
this.closeMenu();
}
}
},
handleEscapePressed(event) {
if (event.key === "Escape") {
this.closeMenu();
event.preventDefault();
}
},
removeCurrentActive() {
const currentActiveElement = this.$refs.menu.querySelector("li.active");
if (currentActiveElement) {
currentActiveElement.classList.remove("active");
}
},
focusAction() {
const focusElement = this.getFocusableMenuItemElements()[this.focusIndex];
if (focusElement) {
this.removeCurrentActive();
const liMenuParent = focusElement.closest("li.action");
focusElement.focus();
if (liMenuParent) {
liMenuParent.classList.add("active");
}
}
},
focusPreviousAction(event) {
if (this.opened) {
if (this.focusIndex === 0) {
this.focusLastAction(event);
} else {
this.preventIfEvent(event);
this.focusIndex = this.focusIndex - 1;
}
this.focusAction();
}
},
focusNextAction(event) {
if (this.opened) {
const indexLength = this.getFocusableMenuItemElements().length - 1;
if (this.focusIndex === indexLength) {
this.focusFirstAction(event);
} else {
this.preventIfEvent(event);
this.focusIndex = this.focusIndex + 1;
}
this.focusAction();
}
},
focusFirstAction(event) {
if (this.opened) {
this.preventIfEvent(event);
const firstCheckedIndex = [...this.getFocusableMenuItemElements()].findIndex((button) => {
return button.getAttribute("aria-checked") === "true" && button.getAttribute("role") === "menuitemradio";
});
this.focusIndex = firstCheckedIndex > -1 ? firstCheckedIndex : 0;
this.focusAction();
}
},
focusLastAction(event) {
if (this.opened) {
this.preventIfEvent(event);
this.focusIndex = this.getFocusableMenuItemElements().length - 1;
this.focusAction();
}
},
preventIfEvent(event) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
},
onFocus(event) {
this.$emit("focus", event);
},
onBlur(event) {
this.$emit("blur", event);
if (this.actionsMenuSemanticType === "tooltip") {
if (this.$refs.menu && this.getFocusableMenuItemElements().length === 0) {
this.closeMenu(false);
}
}
},
onClick(event) {
this.$emit("click", event);
}
},
/**
* The render function to display the component
*
* @param {Function} h The function to create VNodes
* @return {object|undefined} The created VNode
*/
render(h) {
const actions = (this.$slots.default || []).filter((action) => this.getActionName(action));
if (actions.length === 0) {
return;
}
let validInlineActions = actions.filter(this.isValidSingleAction);
if (this.forceMenu && validInlineActions.length > 0 && this.inline > 0) {
Vue__default.default.util.warn("Specifying forceMenu will ignore any inline actions rendering.");
validInlineActions = [];
}
const inlineActions = validInlineActions.slice(0, this.inline);
const menuActions = actions.filter((action) => !inlineActions.includes(action));
if (this.forceSemanticType) {
this.actionsMenuSemanticType = this.forceSemanticType;
} else {
const textInputActions = ["NcActionInput", "NcActionTextEditable"];
const menuItemsActions = ["NcActionButton", "NcActionButtonGroup", "NcActionCheckbox", "NcActionRadio"];
const linkActions = ["NcActionLink", "NcActionRouter"];
const hasTextInputAction = menuActions.some((action) => textInputActions.includes(this.getActionName(action)));
const hasMenuItemAction = menuActions.some((action) => menuItemsActions.includes(this.getActionName(action)));
const hasLinkAction = menuActions.some((action) => linkActions.includes(this.getActionName(action)));
if (hasTextInputAction) {
this.actionsMenuSemanticType = "dialog";
} else if (hasMenuItemAction) {
this.actionsMenuSemanticType = "menu";
} else if (hasLinkAction) {
this.actionsMenuSemanticType = "expanded";
} else {
const ncActions = actions.filter((action) => this.getActionName(action).startsWith("NcAction"));
if (ncActions.length === actions.length) {
this.actionsMenuSemanticType = "tooltip";
} else {
this.actionsMenuSemanticType = "unknown";
}
}
}
const renderInlineAction = (action) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D;
const iconProp = (_b = (_a = action == null ? void 0 : action.componentOptions) == null ? void 0 : _a.propsData) == null ? void 0 : _b.icon;
const icon = (_f = (_e = (_d = (_c = action == null ? void 0 : action.data) == null ? void 0 : _c.scopedSlots) == null ? void 0 : _d.icon()) == null ? void 0 : _e[0]) != null ? _f : this.isIconUrl(iconProp) ? h("img", { class: "action-item__menutoggle__icon", attrs: { src: iconProp, alt: "" } }) : h("span", { class: ["icon", iconProp] });
const attrs = ((_g = action == null ? void 0 : action.data) == null ? void 0 : _g.attrs) || {};
const clickListener = (_i = (_h = action == null ? void 0 : action.componentOptions) == null ? void 0 : _h.listeners) == null ? void 0 : _i.click;
const text = (_n = (_m = (_l = (_k = (_j = action == null ? void 0 : action.componentOptions) == null ? void 0 : _j.children) == null ? void 0 : _k[0]) == null ? void 0 : _l.text) == null ? void 0 : _m.trim) == null ? void 0 : _n.call(_m);
const ariaLabel = ((_p = (_o = action == null ? void 0 : action.componentOptions) == null ? void 0 : _o.propsData) == null ? void 0 : _p.ariaLabel) || text;
const buttonText = this.forceName ? text : "";
let title = (_r = (_q = action == null ? void 0 : action.componentOptions) == null ? void 0 : _q.propsData) == null ? void 0 : _r.title;
if (!(this.forceName || title)) {
title = text;
}
const propsToForward = { ...(_t = (_s = action == null ? void 0 : action.componentOptions) == null ? void 0 : _s.propsData) != null ? _t : {} };
const nativeType = ["submit", "reset"].includes(propsToForward.type) ? propsToForward.modelValue : "button";
delete propsToForward.modelValue;
delete propsToForward.type;
return h(
"NcButton",
{
class: [
"action-item action-item--single",
(_u = action == null ? void 0 : action.data) == null ? void 0 : _u.staticClass,
(_v = action == null ? void 0 : action.data) == null ? void 0 : _v.class
],
attrs: {
...attrs,
"aria-label": ariaLabel,
title
},
ref: (_w = action == null ? void 0 : action.data) == null ? void 0 : _w.ref,
props: {
// If it has a menuName, we use a secondary button
type: this.type || (buttonText ? "secondary" : "tertiary"),
disabled: this.disabled || ((_y = (_x = action == null ? void 0 : action.componentOptions) == null ? void 0 : _x.propsData) == null ? void 0 : _y.disabled),
pressed: (_A = (_z = action == null ? void 0 : action.componentOptions) == null ? void 0 : _z.propsData) == null ? void 0 : _A.modelValue,
nativeType,
...propsToForward
},
on: {
focus: this.onFocus,
blur: this.onBlur,
// forward any pressed state from NcButton just like NcActionButton does
"update:pressed": (_D = (_C = (_B = action == null ? void 0 : action.componentOptions) == null ? void 0 : _B.listeners) == null ? void 0 : _C["update:modelValue"]) != null ? _D : () => {
},
// If we have a click listener,
// we bind it to execute on click and forward the click event
...!!clickListener && {
click: (event) => {
if (clickListener) {
clickListener(event);
}
}
}
}
},
[
h("template", { slot: "icon" }, [icon]),
buttonText
]
);
};
const renderActionsPopover = (actions2) => {
var _a, _b;
const triggerIcon = ((_a = this.$slots.icon) == null ? void 0 : _a[0]) || (this.defaultIcon ? h("span", { class: ["icon", this.defaultIcon] }) : h(DotsHorizontal.DotsHorizontal, {
props: {
size: 20
}
}));
return h(
"NcPopover",
{
ref: "popover",
props: {
delay: 0,
handleResize: true,
shown: this.opened,
placement: this.placement,
boundary: this.boundariesElement,
container: this.container,
popoverBaseClass: "action-item__popper",
popupRole: this.config.popupRole,
setReturnFocus: this.config.withFocusTrap ? (_b = this.$refs.triggerButton) == null ? void 0 : _b.$el : null,
focusTrap: this.config.withFocusTrap
},
// For some reason the popover component
// does not react to props given under the 'props' key,
// so we use both 'attrs' and 'props'
attrs: {
delay: 0,
handleResize: true,
shown: this.opened,
placement: this.placement,
boundary: this.boundariesElement,
container: this.container,
...this.manualOpen && { triggers: [] }
},
on: {
show: this.openMenu,
"apply-show": this.onOpen,
hide: this.closeMenu,
"apply-hide": this.onClosed
}
},
[
h("NcButton", {
class: "action-item__menutoggle",
props: {
type: this.triggerBtnType,
disabled: this.disabled
},
slot: "trigger",
ref: "triggerButton",
attrs: {
id: this.triggerRandomId,
"aria-label": this.menuName ? null : this.ariaLabel,
...this.config.triggerA11yAttr
},
on: {
focus: this.onFocus,
blur: this.onBlur,
click: this.onClick,
keydown: this.onTriggerKeydown
}
}, [
h("template", { slot: "icon" }, [triggerIcon]),
this.menuName
]),
h("div", {
class: {
open: this.opened
},
attrs: {
tabindex: "-1",
...this.config.popoverContainerA11yAttrs
},
on: {
keydown: this.onKeydown,
mousemove: this.onMouseFocusAction
},
ref: "menu"
}, [
h("ul", {
attrs: {
tabindex: "-1",
...this.config.popoverUlA11yAttrs
},
ref: "menuList"
}, [
actions2
])
])
]
);
};
if (actions.length === 1 && validInlineActions.length === 1 && !this.forceMenu) {
return renderInlineAction(actions[0]);
}
this.$nextTick(() => {
if (this.opened && this.$refs.menu) {
this.resizePopover();
const isAnyActive = this.$refs.menu.querySelector("li.active") || [];
if (isAnyActive.length === 0) {
this.focusFirstAction();
}
}
});
if (inlineActions.length > 0 && this.inline > 0) {
return h(
"div",
{
class: [
"action-items",
"action-item--".concat(this.triggerBtnType)
]
},
[
// Render inline actions
...inlineActions.map(renderInlineAction),
// render the rest within the popover menu
menuActions.length > 0 ? h(
"div",
{
class: [
"action-item",
{
"action-item--open": this.opened
}
]
},
[
renderActionsPopover(menuActions)
]
) : null
]
);
}
return h(
"div",
{
class: [
"action-item action-item--default-popover",
"action-item--".concat(this.triggerBtnType),
{
"action-item--open": this.opened
}
]
},
[
renderActionsPopover(actions)
]
);
}
};
const _sfc_render = null;
const _sfc_staticRenderFns = null;
var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns,
false,
null,
"fcbbc5a9"
);
const NcActions = __component__.exports;
exports.NcActions = NcActions;