UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

553 lines (552 loc) 22.8 kB
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); require("./kendo.icons.js"); require("./kendo.userevents.js"); //#region ../src/kendo.drawer.js const __meta__ = { id: "drawer", name: "Drawer", category: "web", description: "The Kendo Drawer widget provides slide to reveal sidebar", depends: ["userevents", "icons"] }; (function($, undefined) { const kendo = window.kendo, Widget = kendo.ui.Widget, SHOW = "show", HIDE = "hide", FOCUSED = "k-focus", keys = kendo.keys, ITEMCLICK = "itemClick", KENDO_KEYDOWN = "kendoKeydown", TABINDEX = "tabIndex", PUSH = "push", OVERLAY = "overlay", LEFT = "left", RIGHT = "right", DRAWER_ITEMS_CLASS = "k-drawer-items"; const Drawer = kendo.ui.Widget.extend({ init: function(element, options) { const that = this; let userEvents; that._originalItems = options && options.items; Widget.fn.init.call(this, element, options); options = that.options; that._element(element); that._wrapper(element); that._navigatable(); that.position(); that._mode(); if (options.mini) that._miniMode(); that._initDrawerItems(); if (options.mini && options.mode != PUSH) that._setBodyOffset(); userEvents = this.userEvents = new kendo.UserEvents(options.mode != PUSH ? $(document.body) : this.drawerContainer, { fastTap: true, allowSelection: true }); that.tap = function(e) { let isParentItem = false; if ($.contains(that.drawerItemsWrapper.filter(".k-drawer-items")[0], e.event.target)) { const tappedItem = $(e.event.target).closest("[data-role='drawer-item']"); isParentItem = tappedItem.length > 0 && tappedItem.find(".k-drawer-toggle").length > 0; that._itemClick(e); } if (!isParentItem && options.autoCollapse && that.visible && !that.trigger("hide", { sender: this })) { that.hide(); e.preventDefault(); } }; if (this.options.swipeToOpen) { userEvents.bind("start", (e) => that._start(e)); userEvents.bind("move", (e) => that._update(e)); userEvents.bind("end", (e) => that._end(e)); userEvents.bind("tap", that.tap); } else userEvents.bind("press", that.tap); if (options.minHeight && options.mode == PUSH) that.drawerContainer.css("min-height", options.minHeight); if (that._showWatermarkOverlay) that._showWatermarkOverlay(that.drawerContainer[0]); if (options.expanded) { that._removeTransition(); that.show(); } kendo.ui.Widget.fn.endInit.call(that); }, _element: function() { const that = this; const element = that.element; const options = that.options; that.contentElement = element.children().wrapAll("<div class='k-drawer-content'></div>").parent(); if (options.template instanceof Function) that.drawerElement = $(options.template()); else if (options.template) that.drawerElement = $(options.template); else if (options.items && options.items.length) that.drawerElement = $(that._renderItems(options.items, 0)); else that.drawerElement = $(options.template); element.addClass("k-drawer"); }, _renderItems: function(items, level) { const renderInline = arguments[2] === true; const isMini = arguments[3] === true; const html = []; if (!renderInline) html.push("<ul class='k-drawer-items'>"); items.forEach((item) => { item = item || {}; if (item.separator) { html.push("<li data-role='drawer-separator'></li>"); return; } const itemTemplate = isMini ? item.miniTemplate : item.template; const hasChildren = item.items && item.items.length; if (itemTemplate instanceof Function) { html.push(itemTemplate(item)); if (hasChildren) html.push(this._renderItems(item.items, level + 1, true, isMini)); return; } let icon = ""; if (item.icon) icon = kendo.ui.icon({ icon: item.icon }); const classNames = []; let disabledAttribute = ""; let toggleIcon = ""; if (item.enabled === false) { classNames.push("k-disabled"); disabledAttribute = " aria-disabled='true'"; } if (item.cssClass) classNames.push(kendo.htmlEncode(item.cssClass)); if (hasChildren) toggleIcon = `<span class='k-spacer'></span><span class='k-drawer-toggle'>${kendo.ui.icon({ icon: this._hasSelectedDescendant(item) ? "chevron-up" : "chevron-down" })}</span>`; const classAttribute = classNames.length ? ` class='${classNames.join(" ")}'` : ""; const itemText = item.text != null ? item.text : ""; html.push(`<li data-role='drawer-item' data-level='${level}'${classAttribute}${disabledAttribute}>${icon}${isMini ? "" : `<span class='k-item-text'>${kendo.htmlEncode(itemText)}</span>`}${toggleIcon}</li>`); if (hasChildren) html.push(this._renderItems(item.items, level + 1, true, isMini)); }); if (!renderInline) html.push("</ul>"); return html.join(""); }, _generatedItems: function(items) { let generatedItems = []; (items || []).forEach((item) => { item = item || {}; if (!item.separator) generatedItems.push(item); if (item.items && item.items.length) generatedItems = generatedItems.concat(this._generatedItems(item.items)); }); return generatedItems; }, _itemMapEntry: function(item) { return (this._itemsMap || []).find((entry) => entry.element === item[0]); }, _hasSelectedDescendant: function(item) { return (item && item.items || []).some((child) => { child = child || {}; return !child.separator && (child.selected || this._hasSelectedDescendant(child)); }); }, _navigatable: function() { const element = this.element; element.find("[data-role='drawer-item']").first().parent().attr("role", "menubar").attr("aria-orientation", "vertical"); if (!this.options.navigatable) return; element.attr(TABINDEX, 0).on("focus.kendoDrawer", this._focus.bind(this)).on("focusout.kendoDrawer", this._blur.bind(this)).on("keydown.kendoDrawer", this, this._keyDown.bind(this)); }, _blur: function() { if (this._current) this._current.removeClass(FOCUSED); }, _focus: function() { this._setCurrent(this._current ? this._current : this.drawerItemsWrapper.find("[data-role='drawer-item']").eq(0)); }, _setCurrent: function(current) { const id = kendo.guid(); const next = $(current); if (this._current) { $(this._current).removeClass(FOCUSED).removeAttr("id"); this.drawerItemsWrapper.removeAttr("aria-activedescendant"); } next.attr("id", id).addClass(FOCUSED); this.drawerItemsWrapper.attr("aria-activedescendant", id); this._current = next; }, _keyDown: function(e) { let handled = false; const current = this._current; let next; if (e.keyCode == keys.UP) { handled = true; next = current.prevAll("[data-role='drawer-item']").first(); if (next.length) this._setCurrent(next); else this._setCurrent(current.parent().find("[data-role='drawer-item']").last()); } if (e.keyCode == keys.DOWN) { handled = true; next = current.nextAll("[data-role='drawer-item']").first(); if (next.length) this._setCurrent(next); else this._setCurrent(current.parent().find("[data-role='drawer-item']").first()); } if (e.keyCode == keys.HOME) { handled = true; this._setCurrent(this.drawerItemsWrapper.find("[data-role='drawer-item']").eq(0)); } if (e.keyCode == keys.END) { handled = true; this._setCurrent(this.drawerItemsWrapper.find("[data-role='drawer-item']").last()); } if (e.keyCode == keys.SPACEBAR || e.keyCode == keys.ENTER) { handled = true; this.tap({ event: { target: current[0] }, preventDefault: $.noop }); } if (e.keyCode == keys.ESC) { handled = true; this.hide(); } if (handled) e.preventDefault(); }, _wrapper: function() { const options = this.options; const drawerElement = this.drawerElement; const element = this.element; const contentElement = this.contentElement; const drawerItemsWrapper = this.drawerItemsWrapper = drawerElement; const drawerWrapper = this.drawerWrapper = drawerItemsWrapper.wrapAll("<div class='k-drawer-wrapper'></div>").parent(); const drawerContainer = this.drawerContainer = element.wrap("<div class='k-drawer-container'></div>").parent(); drawerElement.filter("ul").addClass(DRAWER_ITEMS_CLASS); if (options.mini) { if (options.mini.width) drawerWrapper.width(options.mini.width); } else drawerWrapper.width(0); drawerContainer.append(contentElement); element.append(drawerWrapper); }, _addTransition: function() { this.drawerWrapper.css("transition", "all .3s ease-out"); }, _removeTransition: function() { this.drawerWrapper.css("transition", "none"); }, _setBodyOffset: function() { const overlayMiniOffset = this.element.outerWidth(); if (this.leftPositioned) $(document.body).css("padding-left", overlayMiniOffset); else $(document.body).css("padding-right", overlayMiniOffset); }, _initDrawerItems: function() { const options = this.options; const drawerItemsWrapper = this.drawerItemsWrapper; const drawerItems = drawerItemsWrapper.find("[data-role='drawer-item']"); const separatorItems = drawerItemsWrapper.find("[data-role='drawer-separator']"); let selectedItemIndex = -1; let generatedItems; const generatedMiniItems = !!this._miniTemplate && !!options.items && options.items.length && !options.template && !(options.mini && options.mini.template); drawerItems.addClass("k-drawer-item").attr("role", "menuitem"); separatorItems.addClass("k-drawer-item k-drawer-separator").attr("role", "separator"); this._itemsMap = null; if (options.items && options.items.length && !options.template) { generatedItems = this._generatedItems(this._originalItems || options.items); if (!(options.mini && options.mini.template)) this._itemsMap = []; drawerItems.each((index, element) => { const dataItem = generatedItems[index]; if (!dataItem) return; if (dataItem.attr && !(generatedMiniItems && dataItem.miniTemplate instanceof Function || !generatedMiniItems && dataItem.template instanceof Function)) { const attrCopy = $.extend({}, dataItem.attr); if (attrCopy["class"]) { $(element).addClass(attrCopy["class"]); delete attrCopy["class"]; } $(element).attr(attrCopy); } if (this._itemsMap) this._itemsMap.push({ element, dataItem }); if (selectedItemIndex < 0 && dataItem.selected) selectedItemIndex = index; }); if (selectedItemIndex >= 0 && !(this._selectedItemIndex >= 0)) this._selectedItemIndex = selectedItemIndex; } this._toggleLevelClasses(!!this.visible); if (options.items && options.items.length && !options.template) { this._collapseAllChildren(drawerItems); if (this._itemsMap) drawerItems.each((i, item) => { const entry = this._itemMapEntry($(item)); if (entry && entry.dataItem && entry.dataItem.expanded) this._expandItem($(item), drawerItems, i); }); if (this._selectedItemIndex >= 0) this._expandAncestors(drawerItems, this._selectedItemIndex); } drawerItems.each((i, item) => { const dataItemText = generatedMiniItems && generatedItems[i] && generatedItems[i].text; item.setAttribute("aria-label", dataItemText || item.textContent.trim()); }); if (this._selectedItemIndex >= 0) { drawerItems.removeClass("k-selected"); drawerItems.eq(this._selectedItemIndex).addClass("k-selected"); } }, _toggleLevelClasses: function(flag) { this.drawerItemsWrapper.find("[data-role='drawer-item']").each((i, item) => { const levelClass = "k-level-" + ($(item).data("level") || 0); $(item).toggleClass(levelClass, flag); }); }, _mode: function() { const options = this.options; const drawerContainer = this.drawerContainer; if (options.mode == PUSH) drawerContainer.addClass("k-drawer-push"); else { drawerContainer.addClass("k-drawer-overlay"); const overlayContainer = this.overlayContainer = $("<div class=\"k-overlay\"></div>"); overlayContainer.hide(); drawerContainer.prepend(overlayContainer); } }, _miniMode: function() { const options = this.options; const drawerContainer = this.drawerContainer; const miniWidth = options.mini.width; let miniTemplate = this._miniTemplate = options.mini.template; const drawerItemsWrapper = this.drawerItemsWrapper; const drawerWrapper = this.drawerWrapper; drawerContainer.addClass("k-drawer-mini"); if (!miniTemplate && options.items && options.items.length && !options.template) miniTemplate = this._miniTemplate = this._renderItems(options.items, 0, true, true); if (miniTemplate) if (miniTemplate instanceof Function) drawerItemsWrapper.html($(miniTemplate())); else drawerItemsWrapper.html($(miniTemplate)); if (miniWidth) drawerWrapper.width(miniWidth); this.minWidth = options.mini.width || this.drawerWrapper.width(); }, setOptions: function(options) { const that = this; let hasItems; let itemContent; let isMiniState; let drawerItems; Widget.fn.setOptions.call(that, options); if (!("items" in options)) return; that._originalItems = options.items; if (that.options.template) return; hasItems = that.options.items && that.options.items.length; itemContent = hasItems ? that._renderItems(that.options.items, 0, true) : ""; isMiniState = that.options.mini && that.drawerContainer.hasClass("k-drawer-mini"); if (that.options.mini) if (that.options.mini.template) that._miniTemplate = that.options.mini.template; else that._miniTemplate = hasItems ? that._renderItems(that.options.items, 0, true, true) : ""; else that._miniTemplate = null; if (isMiniState && that._miniTemplate) if (that._miniTemplate instanceof Function) that.drawerItemsWrapper.html($(that._miniTemplate())); else that.drawerItemsWrapper.html($(that._miniTemplate)); else that.drawerItemsWrapper.html(itemContent); that._current = null; that._selectedItemIndex = -1; that._itemsMap = null; that._initDrawerItems(); drawerItems = that.drawerItemsWrapper.find("[data-role='drawer-item']"); drawerItems.removeClass("k-selected"); that._selectItem(); }, show: function() { const drawerWrapper = this.drawerWrapper; const drawerContainer = this.drawerContainer; const options = this.options; const isExpanded = drawerContainer.hasClass("k-drawer-expanded"); const miniTemplate = this._miniTemplate; const drawerItemsWrapper = this.drawerItemsWrapper; if (!isExpanded) { drawerContainer.addClass("k-drawer-expanded"); this.visible = true; } if (miniTemplate) { if (options.template) { const tpl = options.template instanceof Function ? options.template() : options.template; drawerItemsWrapper.html(tpl); } else drawerItemsWrapper.html(this._renderItems(this._originalItems || options.items, 0, true)); this._initDrawerItems(); this._selectItem(); } drawerWrapper.width(options.width); if (options.mini) drawerContainer.removeClass("k-drawer-mini"); if (options.mode === OVERLAY) { this.overlayContainer.show(); this.visible = true; } this._toggleLevelClasses(true); }, hide: function() { const drawerWrapper = this.drawerWrapper; const drawerContainer = this.drawerContainer; const options = this.options; const drawerItemsWrapper = this.drawerItemsWrapper; const miniTemplate = this._miniTemplate; const miniWidth = options.mini && options.mini.width; this._addTransition(); if (this._miniTemplate) { drawerItemsWrapper.html(miniTemplate); this._initDrawerItems(); this._selectItem(); } if (options.mini) { drawerContainer.addClass("k-drawer-mini"); if (miniWidth) drawerWrapper.width(miniWidth); else drawerWrapper.width(""); } else drawerWrapper.width(0); if (this.visible) { drawerContainer.removeClass("k-drawer-expanded"); this.visible = false; } if (options.mode === OVERLAY) this.overlayContainer.hide(); this._toggleLevelClasses(false); }, position: function(value) { const options = this.options; const position = value || options.position; if (position == RIGHT) { this.element.removeClass("k-drawer-start"); this.element.addClass("k-drawer-end"); } else { this.element.removeClass("k-drawer-end"); this.element.addClass("k-drawer-start"); } this.leftPositioned = position === LEFT; }, _start: function(e) { const options = this.options; const drawerItemsWrapper = this.drawerItemsWrapper; const userEvents = e.sender; if (Math.abs(e.x.velocity) < Math.abs(e.y.velocity) || kendo.triggeredByInput(e.event)) { userEvents.cancel(); return; } if (this.drawerMini) drawerItemsWrapper.html(this.drawerElement); this._removeTransition(); if (options.mode != PUSH) this.overlayContainer.show(); }, _update: function(e) { if (this.options.mode == PUSH) this._push(e); else this._overlay(e); }, _end: function(e) { const velocity = e.x.velocity; const options = this.options; const pastHalf = this.drawerWrapper.width() > options.width / 2; const velocityThreshold = .8; let shouldShow; this._addTransition(); if (this.leftPositioned) shouldShow = velocity > -.8 && (velocity > velocityThreshold || pastHalf); else shouldShow = velocity < velocityThreshold && (velocity < -.8 || pastHalf); if (shouldShow) if (this.trigger("show", { sender: this })) { e.preventDefault(); this.hide(); } else this.show(); else if (this.trigger("hide", { sender: this })) { e.preventDefault(); this.show(); } else this.hide(); }, _overlay: function(moveEventArgs) { const options = this.options; const minWidth = options.mini && options.mini.width || this.minWidth || 0; const drawerWrapper = this.drawerWrapper; const updatedPosition = drawerWrapper.width() + (this.leftPositioned ? moveEventArgs.x.delta : -moveEventArgs.x.delta); const limitedPosition = Math.min(Math.max(updatedPosition, minWidth), options.width); moveEventArgs.event.preventDefault(); moveEventArgs.event.stopPropagation(); drawerWrapper.width(limitedPosition); }, _push: function(moveEventArgs) { const options = this.options; const minWidth = options.mini && options.mini.width || this.minWidth || 0; const drawerWrapper = this.drawerWrapper; const updatedPosition = drawerWrapper.width() + (this.leftPositioned ? moveEventArgs.x.delta : -moveEventArgs.x.delta); const limitedPosition = Math.min(Math.max(updatedPosition, minWidth), options.width); moveEventArgs.event.preventDefault(); moveEventArgs.event.stopPropagation(); drawerWrapper.width(limitedPosition); }, _selectItem: function(item) { const drawerItems = this.drawerItemsWrapper.find("[data-role='drawer-item']"); let itemMapEntry; let selectedItemIndex; if (item) { item.addClass("k-selected"); itemMapEntry = this._itemMapEntry(item); this.trigger("itemClick", { item, dataItem: itemMapEntry && itemMapEntry.dataItem, sender: this }); this._selectedItemIndex = drawerItems.index(item); return; } selectedItemIndex = this._selectedItemIndex; if (selectedItemIndex >= 0) drawerItems.eq(selectedItemIndex).addClass("k-selected"); }, _collapseAllChildren: function(drawerItems) { drawerItems.each((_, item) => { if (parseInt($(item).data("level") || 0, 10) > 0) $(item).hide(); }); }, _expandItem: function(item, drawerItems, itemIndex) { const level = parseInt(item.data("level") || 0, 10); item.addClass("k-expanded"); const toggleChrome = item.find(".k-drawer-toggle"); if (toggleChrome.length) toggleChrome.html(kendo.ui.icon({ icon: "chevron-up" })); for (let i = itemIndex + 1; i < drawerItems.length; i++) { const childItem = drawerItems.eq(i); const childLevel = parseInt(childItem.data("level") || 0, 10); if (childLevel <= level) break; if (childLevel === level + 1) childItem.show(); } }, _expandAncestors: function(drawerItems, selectedIndex) { const selectedLevel = parseInt(drawerItems.eq(selectedIndex).data("level") || 0, 10); if (selectedLevel === 0) return; let currentLevel = selectedLevel; for (let i = selectedIndex - 1; i >= 0; i--) { const item = drawerItems.eq(i); const level = parseInt(item.data("level") || 0, 10); if (level < currentLevel) { this._expandItem(item, drawerItems, i); currentLevel = level; if (level === 0) break; } } }, _toggleChildren: function(item) { const level = parseInt(item.data("level") || 0, 10); const drawerItems = this.drawerItemsWrapper.find("[data-role='drawer-item']"); const itemIndex = drawerItems.index(item); const isExpanded = item.hasClass("k-expanded"); const toggleChrome = item.find(".k-drawer-toggle"); if (isExpanded) { item.removeClass("k-expanded"); for (let i = itemIndex + 1; i < drawerItems.length; i++) { const childItem = drawerItems.eq(i); if (parseInt(childItem.data("level") || 0, 10) <= level) break; childItem.hide(); if (childItem.hasClass("k-expanded")) { childItem.removeClass("k-expanded"); childItem.find(".k-drawer-toggle").html(kendo.ui.icon({ icon: "chevron-down" })); } } if (toggleChrome.length) toggleChrome.html(kendo.ui.icon({ icon: "chevron-down" })); } else this._expandItem(item, drawerItems, itemIndex); }, _itemClick: function(e) { const that = this; const item = $(e.event.target).closest("[data-role='drawer-item']"); if (!item || !item.length || item.hasClass("k-disabled")) return; that.drawerItemsWrapper.find("[data-role='drawer-item']").removeClass("k-selected"); that._selectItem(item); if (that.options.navigatable) that._setCurrent(item); if (!that.options.template && item.find(".k-drawer-toggle").length) that._toggleChildren(item); }, destroy: function() { if (this.options.mode != PUSH) if (this.leftPositioned) $(document.body).css("padding-left", 0); else $(document.body).css("padding-right", 0); Widget.fn.destroy.call(this); this.userEvents.destroy(); kendo.destroy(this.element); this.element = this.drawerWrapper = this.drawerElement = this.drawerContainer = this.drawerItemsWrapper = this._itemsMap = this._miniTemplate = this._originalItems = null; }, options: { name: "Drawer", autoCollapse: true, expanded: false, items: null, position: LEFT, mode: "overlay", swipeToOpen: true, width: 280, mini: false, navigatable: false, template: "" }, events: [ HIDE, SHOW, ITEMCLICK, KENDO_KEYDOWN ] }); kendo.ui.plugin(Drawer); })(window.kendo.jQuery); var kendo_drawer_default = kendo; //#endregion exports.__meta__ = __meta__; exports.default = kendo_drawer_default;