@progress/kendo-vue-buttons
Version:
300 lines (299 loc) • 9.46 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2026 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import { defineComponent as w, createVNode as o, ref as g } from "vue";
import { templateRendering as M, getListeners as S, getTabIndex as A, Icon as $, classNames as p, setRef as k, Keys as n, canUseDOM as F, kendoThemeMaps as I, getRef as x, validatePackage as R, guid as c } from "@progress/kendo-vue-common";
import { FloatingActionButtonItem as B } from "./FloatingActionButtonItem.mjs";
import { packageMetadata as E } from "../package-metadata.mjs";
import { getPopupAlign as N, getAnchorAlign as P, position as O, getTextDirectionClass as K } from "./utils.mjs";
import { Popup as j } from "@progress/kendo-vue-popup";
const G = /* @__PURE__ */ w({
name: "KendoVueFloatingActionButton",
props: {
id: String,
dir: String,
tabIndex: Number,
accessKey: String,
disabled: {
type: Boolean,
default: !1
},
icon: String,
svgIcon: Object,
iconClass: String,
items: [Object, Array],
item: [String, Function, Object],
text: String,
alignOffset: Object,
opened: {
type: Boolean,
default: void 0
},
align: {
type: Object,
default: function() {
return {
vertical: "bottom",
horizontal: "end"
};
}
},
positionMode: {
type: String,
default: function() {
return "fixed";
}
},
popupSettings: {
type: Object,
default: function() {
return {};
}
},
rounded: String,
fillMode: {
type: String,
validator: function(e) {
return ["flat", "link", "outline", "solid"].includes(e);
}
},
size: String,
themeColor: String
},
emits: {
click: (e) => !0,
mousedown: (e) => !0,
mouseup: (e) => !0,
open: (e) => !0,
close: (e) => !0,
itemclick: (e) => !0,
focus: (e) => !0,
blur: (e) => !0,
keydown: (e) => !0
},
data() {
return {
currentOpened: !1,
currentFocused: !1,
focusedIndex: -1,
currentDir: "ltr",
isRtl: !1
};
},
created() {
R(E), this.element = void 0, this._anchor = c(), this.listId = c(), this.buttonId = c();
},
mounted() {
this.element = this.kendoAnchorRef, this.list = x(this, "list"), this.popup = x(this, "popup"), this.currentDir = this.$props.dir !== void 0 ? this.$props.dir : this.$el && getComputedStyle(this.$el).direction === "rtl" || !1, this.isRtl = this.currentDir === "rtl", this.opened !== void 0 && O(this.$el, this.$props.align, this.$props.alignOffset, this.isRtl);
},
updated() {
O(this.$el, this.$props.align, this.$props.alignOffset, this.isRtl), this.currentFocused && this.element && this.element.focus();
},
computed: {
buttonClassNames() {
const {
size: e,
themeColor: t,
fillMode: i,
rounded: s
} = this.$props;
return {
"k-fab": !0,
[`k-fab-${I.sizeMap[e] || e}`]: e,
[`k-rounded-${I.roundedMap[s] || s}`]: s,
[`k-fab-${i}`]: i,
[`k-fab-${t}`]: t,
"k-disabled": this.$props.disabled,
"k-focus": this.currentFocused,
[`k-${this.$props.align.vertical}-${this.$props.align.horizontal}`]: !0
};
},
computedOpened() {
return this.$props.opened === void 0 ? this.currentOpened : this.$props.opened;
},
rootClassNames() {
return p({
"k-pos-absolute": this.$props.positionMode === "absolute",
"k-pos-fixed": this.$props.positionMode === "fixed"
});
}
},
methods: {
dispatchPopupEvent(e, t) {
this.$props.items && this.$emit(t ? "open" : "close", {
event: e,
isOpened: !t
});
},
handleClick(e) {
if (!(!e.target || this.$props.disabled))
if (!this.$props.items)
this.$emit("click", e, void 0);
else {
const t = !this.computedOpened;
this.currentOpened = t, this.currentFocused = !0, this.focusedIndex = t ? 0 : -1, this.dispatchPopupEvent(e, t);
}
},
handleFocus(e) {
this.currentFocused = !0, this.focusedIndex = this.computedOpened ? 0 : -1, this.$emit("focus", {
event: e
});
},
handleBlur(e) {
const t = this.computedOpened;
this.currentFocused = !1, this.currentOpened = !1, this.focusedIndex = -1, this.$emit("blur", {
event: e
}), t && this.dispatchPopupEvent(e, !1);
},
handleMouseDown(e) {
e.preventDefault(), this.$emit("mousedown", e);
},
handleMouseUp(e) {
this.$emit("mouseup", e);
},
dispatchItemClickEvent(e, t) {
this.$props.items && (this.$props.items[t].disabled || this.$emit("itemclick", e, {
itemProps: this.$props.items[t],
itemIndex: t
}));
},
handleItemClick(e, t) {
!e.target || !this.$props.items || (this.focusedIndex = t, this.currentOpened = !1, this.dispatchItemClickEvent(e, t), this.dispatchPopupEvent(e, !1));
},
handleItemDown(e) {
F && document.activeElement === this.element && e.preventDefault();
},
handleKeyDown(e) {
const t = this.focusedIndex, i = this.$props.items ? this.$props.items.length - 1 : -1, s = this.$props.align.vertical === "bottom";
switch (e.keyCode) {
case n.enter:
case n.space:
t >= 0 && this.dispatchItemClickEvent(e, t), e.preventDefault(), this.currentOpened = !this.currentOpened, this.focusedIndex = this.currentOpened ? -1 : 0;
break;
case n.esc:
e.preventDefault(), this.currentOpened = !1, this.focusedIndex = -1;
break;
case n.home:
e.preventDefault(), this.focusedIndex = 0;
break;
case n.end:
e.preventDefault(), this.focusedIndex = i;
break;
case n.down:
case n.right:
e.preventDefault(), t < i && !s && (this.focusedIndex = t + 1), t > 0 && s && (this.focusedIndex = t - 1);
break;
case n.up:
case n.left:
e.preventDefault(), t > 0 && !s && (this.focusedIndex = t - 1), t < i && s && (this.focusedIndex = t + 1);
break;
}
this.$emit("keydown", e, void 0);
}
},
setup() {
const e = g(null), t = g(null);
return {
chipRef: e,
kendoAnchorRef: t
};
},
render() {
const {
align: e,
disabled: t,
icon: i,
svgIcon: s,
iconClass: h,
id: f,
items: r,
text: a,
tabIndex: v,
accessKey: C,
popupSettings: l
} = this.$props, y = M.call(this, this.$props.item, S.call(this)), D = function() {
return r && r.map(function(d, u) {
return o(B, {
key: u,
index: u,
id: `${this.listId}-${u}`,
disabled: t || d.disabled,
focused: this.focusedIndex === u,
dataItem: d,
item: y,
class: p(d.className, K(this.currentDir || "ltr", e.horizontal)),
onClick: this.handleItemClick,
onDown: this.handleItemDown
}, null);
}, this);
}, m = i && !a, b = (this.element ? this.element.offsetWidth : 0) / 2 - 32 / 2;
return o("div", {
class: this.rootClassNames
}, [o("button", {
ref: (d) => {
this.kendoAnchorRef = d;
},
id: f || this.buttonId,
role: r ? "menubutton" : "button",
type: "button",
"aria-disabled": t,
"aria-expanded": r ? this.computedOpened : void 0,
"aria-haspopup": r,
"aria-label": `${a || ""} floatingactionbutton`,
"aria-owns": r ? this.listId : void 0,
"aria-activedescendant": this.focusedIndex >= 0 && r ? `${this.listId}-${this.focusedIndex}` : void 0,
tabindex: A(v, t),
accesskey: C,
dir: this.currentDir,
disabled: t,
class: this.buttonClassNames,
onClick: this.handleClick,
onMousedown: this.handleMouseDown,
onMouseup: this.handleMouseUp,
onFocusin: this.handleFocus,
onBlur: this.handleBlur,
onKeydown: this.handleKeyDown
}, [i || s ? o($, {
name: i,
icon: s,
class: "k-fab-icon"
}, null) : h ? o($, {
class: h
}, null) : null, a && o("span", {
class: "k-fab-text"
}, [a])]), o(j, {
ref: k(this, "popup"),
show: this.computedOpened,
anchor: this._anchor,
animate: l.animate,
popupClass: p("k-popup-transparent k-fab-popup", l.popupClass),
anchorAlign: l.anchorAlign || P(e, this.isRtl),
popupAlign: l.popupAlign || N(e, this.isRtl),
style: {
boxShadow: "none"
}
}, {
default: () => [o("ul", {
ref: k(this, "list"),
role: "menu",
"aria-labelledby": f,
id: this.listId,
class: p("k-fab-items", {
"k-fab-items-bottom": e.vertical !== "bottom",
"k-fab-items-top": e.vertical === "bottom"
}),
style: {
paddingLeft: m ? b + "px" : void 0,
paddingRight: m ? b + "px" : void 0
}
}, [D.call(this)])]
})]);
}
});
export {
G as FloatingActionButton
};