UNPKG

@progress/kendo-vue-buttons

Version:
266 lines (265 loc) 8.93 kB
/** * @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 $, createVNode as n, ref as k } from "vue"; import { Button as y } from "../Button.mjs"; import { canUseDOM as C, Keys as i, getDefaultSlots as I, guid as a, validatePackage as D, classNames as O, kendoThemeMaps as x, templateRendering as l, getListeners as c } from "@progress/kendo-vue-common"; import w from "./utils/navigation.mjs"; import { ButtonItem as S } from "./ButtonItem.mjs"; import { Popup as B } from "@progress/kendo-vue-popup"; import { getPopupAlign as E, getAnchorAlign as K } from "./utils/popup.mjs"; import { packageMetadata as P } from "../package-metadata.mjs"; const U = /* @__PURE__ */ $({ name: "KendoDropDownButton", emits: { focus: null, blur: null, itemclick: null, open: null, close: null }, props: { accessKey: String, items: { type: Array, default: function() { return []; } }, ariaLabel: String, text: String, textField: String, tabIndex: Number, disabled: Boolean, icon: String, svgIcon: Object, iconClass: String, imageUrl: String, popupSettings: Object, itemRender: [String, Object, Function], item: Function, size: { type: String, default: "medium" }, shape: { type: String, default: "rectangle", validator: function(e) { return [null, "rectangle", "square"].includes(e); } }, rounded: { type: String, default: "medium" }, fillMode: { type: String, default: "solid", validator: function(e) { return [null, "flat", "link", "outline", "solid"].includes(e); } }, themeColor: { type: String, default: "base", validator: function(e) { return [null, "base", "dark", "error", "info", "inverse", "inverse", "light", "primary", "secondary", "success", "tertiary", "warning"].includes(e); } }, opened: { type: Boolean, default: void 0 }, buttonClass: String, dir: String }, created() { this._blurTimeout = null, this._anchor = a(), this.wrapper = null, this.mainButton = null, this.guid = a(), this.buttonsData = [], D(P); }, mounted() { this.mainButton = this.$refs[this._anchor], (this.$props.dir === void 0 && this.isRtl() || this.computedOpened) && this.$forceUpdate(); }, updated() { this.focused && this.element() && (this.mainButton = this.$refs[this._anchor], this.mainButton.focus()); }, data() { return { currentOpened: !1, focused: !1, focusedIndex: -1 }; }, computed: { computedOpened() { return this.$props.opened === void 0 ? this.currentOpened : this.$props.opened; }, wrapperClass() { return { "k-dropdown-button": !0, "k-focus": this.focused }; } }, setup() { return { kendoAnchorRef: k(null) }; }, render() { const e = this.isRtl(), t = e ? "rtl" : void 0, { tabIndex: o, disabled: p } = this.$props, h = I(this); this.buttonsData = this.$props.items; const f = function() { const { item: s, itemRender: r, textField: g } = this.$props; return this.buttonsData.length > 0 ? this.buttonsData.map(function(u, d) { const b = typeof u != "string" ? { ...u, render: l.call(this, u.render, c.call(this)) } : u; return n(S, { class: "k-menu-item", dataItem: b, textField: g, focused: this.focusedIndex === d, onClick: this.onItemClick, onDown: this.onItemDown, render: l.call(this, r, c.call(this)), item: s, index: d, key: d, id: `${this.guid}-${d}` }, null); }, this) : null; }, m = function() { const { popupSettings: s = {}, size: r } = this.$props; return n(B, { anchor: this._anchor, show: this.computedOpened, animate: s.animate, popupClass: O("k-menu-popup", s.popupClass), anchorAlign: s.anchorAlign || K(e), popupAlign: s.popupAlign || E(e), style: e ? { direction: "rtl" } : void 0 }, { default: () => [n("ul", { class: `k-group k-menu-group k-reset k-menu-group-${x.sizeMap[r] || r}`, role: "menu", id: this.guid }, [f.call(this)])] }); }; return n("div", { class: this.wrapperClass, onKeydown: this.onKeyDown, onFocusin: this.onFocus, onFocusout: this.onBlur, dir: t }, [n(y, { size: this.$props.size, shape: this.$props.shape, rounded: this.$props.rounded, fillMode: this.$props.fillMode, themeColor: this.$props.themeColor, onClick: this.onClickMainButton, onMousedown: this.mouseDown, disabled: p || void 0, tabIndex: o, accessKey: this.$props.accessKey, icon: this.$props.icon, svgIcon: this.$props.svgIcon, iconClass: this.$props.iconClass, class: this.$props.buttonClass, imageUrl: this.$props.imageUrl, dir: t, ref: this._anchor, type: "button", "aria-disabled": p, "aria-haspopup": "menu", "aria-expanded": this.computedOpened, "aria-label": this.$props.ariaLabel || `${this.$props.text || ""} dropdownbutton`, "aria-controls": this.guid, "aria-activedescendant": this.focusedIndex !== void 0 && this.focusedIndex >= 0 ? `${this.guid}-${this.focusedIndex}` : void 0 }, { default: () => [this.$props.text, h] }), m.call(this)]); }, methods: { element() { return this.mainButton; }, onKeyDown(e) { if (e.altKey) { !this.computedOpened && e.keyCode === i.down ? (this.dispatchPopupEvent(e, !0), this.focusedIndex = 0, this.currentOpened = !0) : this.computedOpened && e.keyCode === i.up && (this.dispatchPopupEvent(e, !1), this.focusedIndex = -1, this.currentOpened = !1); return; } if (e.keyCode === i.enter || e.keyCode === i.space ? (this.focusedIndex !== void 0 && this.focusedIndex >= 0 && this.dispatchClickEvent(e, this.focusedIndex), e.preventDefault(), this.focusedIndex = this.computedOpened ? -1 : 0, this.currentOpened = !this.computedOpened, this.dispatchPopupEvent(e, this.currentOpened)) : this.computedOpened && e.keyCode === i.esc && (this.focusedIndex = -1, this.currentOpened = !1, this.dispatchPopupEvent(e, this.currentOpened)), this.computedOpened) { const t = w(this.focusedIndex, e.keyCode, e.altKey, this.buttonsData.length); this.focusedIndex = t; const o = e.keyCode === i.up || e.keyCode === i.down || e.keyCode === i.left || e.keyCode === i.right; !e.altKey && o && e.preventDefault(); } }, onFocus(e) { this.focused || (this.focused = !0, this.$emit("focus", e, this, void 0)), this.focusedIndex = this.computedOpened ? 0 : -1, clearTimeout(this._blurTimeout); }, onBlur(e) { clearTimeout(this._blurTimeout), this.createBlurTimeout(e); }, createBlurTimeout(e) { const t = this; this._blurTimeout = setTimeout(() => { C && document.activeElement !== t.$el && (t.focused = !1, t.focusedIndex = -1, t.$emit("blur", e, t, void 0), t.computedOpened && (t.currentOpened = !1, t.dispatchPopupEvent(e, !1))); }, 200); }, onItemClick(e, t) { this.focusedIndex = -1, this.currentOpened = !1, this.dispatchClickEvent(e, t), this.dispatchPopupEvent(e, !1); }, onItemDown(e) { document.activeElement === this.element() && e.preventDefault(); }, mouseDown(e) { e.preventDefault(); }, dispatchClickEvent(e, t) { this.isItemDisabled(t) || this.$emit("itemclick", { event: e, item: this.buttonsData[t], itemIndex: t }); }, onClickMainButton(e) { if (!this.buttonsData.length) return; const t = !this.computedOpened; this.currentOpened = t, this.focused = !0, this.focusedIndex = t ? 0 : -1, this.dispatchPopupEvent(e, t); }, dispatchPopupEvent(e, t) { this.$emit(t ? "open" : "close", e, this, void 0); }, isItemDisabled(e) { return this.buttonsData[e] ? this.buttonsData[e].disabled : this.$props.disabled; }, isRtl() { return this.$props.dir !== void 0 ? this.$props.dir === "rtl" : !!this.$el && getComputedStyle(this.$el).direction === "rtl"; } } }); export { U as DropDownButton };