UNPKG

@progress/kendo-ui

Version:

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

332 lines (331 loc) 11.1 kB
//#region ../src/kendo.segmentedcontrol.js const __meta__ = { id: "segmentedcontrol", name: "SegmentedControl", category: "web", description: "The SegmentedControl widget provides a segmented control UI with selectable buttons.", depends: [ "core", "icons", "html.icon" ] }; (function($, undefined) { const kendo = window.kendo, encode = kendo.htmlEncode, Widget = kendo.ui.Widget, ns = ".kendoSegmentedControl", CLICK = "click", CHANGE = "change", HOVER_CLASS = "k-hover", FOCUS_CLASS = "k-focus", DISABLED_CLASS = "k-disabled", SELECTED_CLASS = "k-selected", BUTTON_SELECTOR = ".k-segmented-control-button", ICON_WRAPPER_CLASS = "k-segmented-control-button-icon", COMPACT = "compact", STRETCH = "stretch", ROLE = "role", ARIA_HIDDEN = "aria-hidden", ARIA_LABEL = "aria-label", ARIA_PRESSED = "aria-pressed", ARIA_DISABLED = "aria-disabled"; const SegmentedControl = Widget.extend({ init: function(element, options) { const that = this; Widget.fn.init.call(that, element, options); that._items = that.options.items || []; that._selectedValue = that.options.selectedValue; that._enabled = that.options.enabled !== false; that._isRtl = kendo.support.isRtl(that.element) || that.element.css("direction") === "rtl"; that._createIconClassMap(); that._render(); that._bindEvents(); that._initResizeObserver(); if (!that._enabled) { that._toggleEnabled(false); } kendo.notify(that); }, options: { name: "SegmentedControl", items: [], selectedValue: null, size: undefined, layoutMode: COMPACT, enabled: true }, events: [CHANGE], _createIconClassMap: function() { const that = this; const items = that._items; const map = that._iconClassMap = new Map(); items.forEach((item) => { if (item.iconClassOnSelection) { map.set(item.value, item.iconClassOnSelection); } }); }, _render: function() { const that = this; const element = that.element; const items = that._items; const size = that.options.size; const sizeEntry = kendo.cssProperties.sizeValues.find(([name]) => name === size); const sizeClass = sizeEntry; const isStretched = that.options.layoutMode === STRETCH; element.addClass(`k-segmented-control k-segmented-control${sizeClass ? `-` + sizeClass[1] : ""}${isStretched ? " k-segmented-control-stretched" : ""}`); element.attr(ROLE, "group"); const thumb = $("<div>").addClass("k-segmented-control-thumb").attr(ARIA_HIDDEN, "true"); element.append(thumb); items.forEach((item, index) => { const button = that._renderButton(item, index); element.append(button); }); that._calculateThumbPosition(); }, _renderButton: function(item, index) { const that = this; const isSelected = item.value === that._selectedValue; const isDisabled = item.enabled === false; const button = $("<button>").attr("type", "button").addClass("k-segmented-control-button").attr("data-value", item.value).attr("data-button-index", index).attr("title", item.text || "").attr(ARIA_PRESSED, (isSelected && !isDisabled).toString()).toggleClass(DISABLED_CLASS, isDisabled).toggleClass(SELECTED_CLASS, isSelected && !isDisabled).prop("disabled", isDisabled); if (isDisabled) { button.attr(ARIA_DISABLED, "true"); } if (item.icon) { const iconClass = ICON_WRAPPER_CLASS + (item.iconClass ? " " + item.iconClass : ""); const icon = $(kendo.html.renderIcon({ icon: item.icon, iconClass })); icon.attr(ARIA_HIDDEN, true); if (isSelected && !isDisabled) { const specialClass = that._iconClassMap.get(item.value); if (specialClass) { icon.addClass(specialClass); } } button.append(icon); } else if (item.iconClass) { button.append(`<span class='${ICON_WRAPPER_CLASS} ${item.iconClass}' ${ARIA_HIDDEN}='true'></span>`); } if (item.text) { const text = $("<span>").addClass("k-segmented-control-button-text").text(encode(item.text)); button.append(text); } else if (item.icon) { button.attr(ARIA_LABEL, item.value); } return button; }, _calculateThumbPosition: function() { const that = this; const selected = that._selectedValue; const totalWidth = kendo._outerWidth(that.element); const totalButtonCount = that._items?.length || 0; if (!totalWidth) { return; } if (!selected) { return; } const buttons = that.element.find("button[data-value]"); const button = buttons.filter(`[data-value="${selected}"]`); const index = button.data("buttonIndex"); const thumb = that.element.find(".k-segmented-control-thumb"); const buttonWidth = kendo._outerWidth(button); let left = 0; let right = 0; let spacing = 0; if (that.options.layoutMode === STRETCH) { const buttonsRightFromTarget = totalButtonCount - 1 - index; left = index * buttonWidth; right = buttonsRightFromTarget * buttonWidth; spacing = (totalWidth - totalButtonCount * buttonWidth) / 2; } else { let totalButtonWidth = 0; buttons.each((btnIndex, btnElement) => { const elementRef = $(btnElement); totalButtonWidth += kendo._outerWidth(elementRef); if (btnIndex < index) { left += kendo._outerWidth(elementRef); } if (btnIndex > index) { right += kendo._outerWidth(elementRef); } }); spacing = (totalWidth - totalButtonWidth) / 2; } if (that._isRtl) { thumb.css({ right: left + spacing, left: right + spacing }); } else { thumb.css({ left: left + spacing, right: right + spacing }); } }, _bindEvents: function() { const that = this; that.element.on(CLICK + ns, BUTTON_SELECTOR, function(e) { const button = $(e.currentTarget); if (!that._enabled || button.hasClass(DISABLED_CLASS)) { return; } const value = button.data("value"); if (value !== that._selectedValue) { that.select(value); } }).on("mouseenter" + ns, BUTTON_SELECTOR, function(e) { const button = $(e.currentTarget); if (that._enabled && !button.hasClass(DISABLED_CLASS)) { button.addClass(HOVER_CLASS); } }).on("mouseleave" + ns, BUTTON_SELECTOR, function(e) { $(e.currentTarget).removeClass(HOVER_CLASS); }).on("focus" + ns, BUTTON_SELECTOR, function(e) { const button = $(e.currentTarget); if (that._enabled && !button.hasClass(DISABLED_CLASS)) { button.addClass(FOCUS_CLASS); } }).on("blur" + ns, BUTTON_SELECTOR, function(e) { $(e.currentTarget).removeClass(FOCUS_CLASS); }); }, select: function(value) { const that = this; if (value === undefined) { return that._selectedValue; } const item = that._items.find((i) => i.value === value); if (!item || item.enabled === false) { return; } const eventArgs = { value, item }; if (that.trigger(CHANGE, eventArgs)) { return; } that._selectedValue = value; that._updateSelectedState(); }, _updateSelectedState: function() { const that = this; const buttons = that.element.find(BUTTON_SELECTOR); const selectedValue = that._selectedValue; buttons.each((_, btnElement) => { const btn = $(btnElement); that._removeSelectionClasses(btn); }); const selectedButton = buttons.filter(`[data-value="${selectedValue}"]`); that._addSelectionClasses(selectedButton, selectedValue); that._calculateThumbPosition(); }, _addSelectionClasses: function(button, selectedValue) { const that = this; const specialSelectedIconClass = that._iconClassMap.get(selectedValue); button.addClass(SELECTED_CLASS); button.attr(ARIA_PRESSED, "true"); const icon = button.find(".k-icon,.k-svg-icon"); if (icon.length && specialSelectedIconClass) { icon.addClass(specialSelectedIconClass); } }, _removeSelectionClasses: function(button) { const that = this; const value = button.data("value"); const specialSelectedIconClass = that._iconClassMap.get(value); button.removeClass(SELECTED_CLASS); button.attr(ARIA_PRESSED, "false"); const icon = button.find(".k-icon,.k-svg-icon"); if (icon.length && specialSelectedIconClass) { icon.removeClass(specialSelectedIconClass); } }, value: function(value) { const that = this; if (value === undefined) { return that._selectedValue; } that._selectedValue = value; that._updateSelectedState(); }, item: function(index) { return this.element.find(BUTTON_SELECTOR).eq(index); }, items: function() { return this.element.find(BUTTON_SELECTOR); }, enable: function(enable) { const that = this; const isEnabled = enable !== false; that._enabled = isEnabled; that._toggleEnabled(isEnabled); }, _toggleEnabled: function(isEnabled) { const that = this; const buttons = that.element.find(BUTTON_SELECTOR); that.element.toggleClass(DISABLED_CLASS, !isEnabled); if (!isEnabled) { buttons.each((_, btnElement) => { const btn = $(btnElement); btn.prop("disabled", true); btn.attr(ARIA_DISABLED, "true"); btn.removeClass(HOVER_CLASS + " " + FOCUS_CLASS); }); } else { buttons.each((idx, btnElement) => { const btn = $(btnElement); const item = that._items[idx]; const isItemDisabled = item && item.enabled === false; btn.prop("disabled", isItemDisabled); if (isItemDisabled) { btn.attr(ARIA_DISABLED, "true"); } else { btn.removeAttr(ARIA_DISABLED); } }); } }, focus: function(item) { const that = this; if (item !== undefined) { const button = item instanceof $ ? item : that.item(item); if (button && button.length) { button[0].focus(); } return; } const buttons = that.element.find(BUTTON_SELECTOR).not(":disabled"); if (buttons.length) { buttons.first()[0].focus(); } }, setOptions: function(options) { const that = this; that.element.empty(); that.element.removeClass(function(index, className) { return (className.match(/(^|\s)k-segmented-control\S*/g) || []).join(" "); }); Widget.fn.setOptions.call(that, options); that._items = that.options.items || []; that._selectedValue = that.options.selectedValue; that._enabled = that.options.enabled !== false; that._isRtl = kendo.support.isRtl(that.element) || that.element.css("direction") === "rtl"; that._createIconClassMap(); that._render(); if (!that._enabled) { that._toggleEnabled(false); } }, _initResizeObserver: function() { const that = this; if (typeof ResizeObserver === "undefined") { return; } that._resizeObserver = new ResizeObserver(function() { that._calculateThumbPosition(); }); that._resizeObserver.observe(that.element[0]); }, destroy: function() { const that = this; if (that._resizeObserver) { that._resizeObserver.disconnect(); that._resizeObserver = null; } that.element.off(ns); Widget.fn.destroy.call(that); } }); kendo.ui.plugin(SegmentedControl); })(window.kendo.jQuery); var kendo_segmentedcontrol_default = kendo; //#endregion export { kendo_segmentedcontrol_default as n, __meta__ as t };