@progress/kendo-vue-buttons
Version:
318 lines (317 loc) • 9.82 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import { defineComponent as v, createVNode as o, ref as g } from "vue";
import { templateRendering as S, getListeners as M, getTabIndex as A, Icon as $, classNames as h, setRef as k, Keys as n, canUseDOM as F, kendoThemeMaps as I, getRef as x, validatePackage as R, guid as f } from "@progress/kendo-vue-common";
import { FloatingActionButtonItem as E } from "./FloatingActionButtonItem.mjs";
import { packageMetadata as B } from "../package-metadata.mjs";
import { getPopupAlign as N, getAnchorAlign as P, position as y, getTextDirectionClass as K } from "./utils.mjs";
import { Popup as j } from "@progress/kendo-vue-popup";
const G = /* @__PURE__ */ v({
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 {};
}
},
shape: {
type: String,
default: function() {
return "rectangle";
}
},
rounded: {
type: String,
default: "full"
},
fillMode: {
type: String,
default: "solid",
validator: function(e) {
return [null, "flat", "link", "outline", "solid"].includes(e);
}
},
size: {
type: String,
default: function() {
return "medium";
}
},
themeColor: {
type: String,
default: function() {
return "primary";
}
}
},
emits: {
click: null,
mousedown: null,
mouseup: null,
open: null,
close: null,
itemclick: null,
focus: null,
blur: null,
keydown: null
},
data() {
return {
currentOpened: !1,
currentFocused: !1,
focusedIndex: -1,
currentDir: "ltr",
isRtl: !1
};
},
created() {
R(B), this.element = void 0, this._anchor = f(), this.listId = f(), this.buttonId = f();
},
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 && y(this.$el, this.$props.align, this.$props.alignOffset, this.isRtl);
},
updated() {
y(this.$el, this.$props.align, this.$props.alignOffset, this.isRtl), this.currentFocused && this.element && this.element.focus();
},
computed: {
buttonClassNames() {
const {
size: e,
icon: t,
shape: s,
themeColor: i,
fillMode: d,
rounded: a
} = this.$props;
return {
"k-fab": !0,
[`k-fab-${s || "rectangle"}`]: s !== null,
[`k-fab-${I.sizeMap[e] || e}`]: e,
[`k-rounded-${I.roundedMap[a] || a}`]: a,
[`k-fab-${d}`]: d,
[`k-fab-${d}-${i}`]: d && i,
"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 h({
"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, !this.computedOpened);
}
},
handleFocus(e) {
this.currentFocused = !0, this.focusedIndex = this.computedOpened ? 0 : -1, this.$emit("focus", e, void 0);
},
handleBlur(e) {
this.currentFocused = !1, this.currentOpened = !1, this.focusedIndex = -1, this.$emit("blur", e, void 0), this.computedOpened && 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, s = this.$props.items ? this.$props.items.length - 1 : -1, i = 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 = s;
break;
case n.down:
case n.right:
e.preventDefault(), t < s && !i && (this.focusedIndex = t + 1), t > 0 && i && (this.focusedIndex = t - 1);
break;
case n.up:
case n.left:
e.preventDefault(), t > 0 && !i && (this.focusedIndex = t - 1), t < s && i && (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: s,
svgIcon: i,
iconClass: d,
id: a,
items: r,
text: u,
tabIndex: O,
accessKey: C,
popupSettings: p
} = this.$props, D = S.call(this, this.$props.item, M.call(this)), w = function() {
return r && r.map(function(l, c) {
return o(E, {
key: c,
index: c,
id: `${this.listId}-${c}`,
disabled: t || l.disabled,
focused: this.focusedIndex === c,
dataItem: l,
item: D,
class: h(l.className, K(this.currentDir || "ltr", e.horizontal)),
onClick: this.handleItemClick,
onDown: this.handleItemDown
}, null);
}, this);
}, m = s && !u, b = (this.element ? this.element.offsetWidth : 0) / 2 - 32 / 2;
return o("div", {
class: this.rootClassNames
}, [o("button", {
ref: (l) => {
this.kendoAnchorRef = l;
},
id: a || this.buttonId,
role: r ? "menubutton" : "button",
type: "button",
"aria-disabled": t,
"aria-expanded": r ? this.computedOpened : void 0,
"aria-haspopup": !!r,
"aria-label": `${u || ""} floatingactionbutton`,
"aria-owns": r ? this.listId : void 0,
"aria-activedescendant": this.focusedIndex >= 0 && r ? `${this.listId}-${this.focusedIndex}` : void 0,
tabindex: A(O, 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
}, [s || i ? o($, {
name: s,
icon: i,
class: "k-fab-icon"
}, null) : d ? o($, {
class: d
}, null) : null, u && o("span", {
class: "k-fab-text"
}, [u])]), o(j, {
ref: k(this, "popup"),
show: this.computedOpened,
anchor: this._anchor,
animate: p.animate,
popupClass: h("k-popup-transparent k-fab-popup", p.popupClass),
anchorAlign: p.anchorAlign || P(e, this.isRtl),
popupAlign: p.popupAlign || N(e, this.isRtl),
style: {
boxShadow: "none"
}
}, {
default: () => [o("ul", {
ref: k(this, "list"),
role: "menu",
"aria-labelledby": a,
id: this.listId,
class: h("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
}
}, [w.call(this)])]
})]);
}
});
export {
G as FloatingActionButton
};