UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

404 lines (403 loc) • 16.6 kB
/** * DevExtreme (esm/ui/toolbar/ui.toolbar.base.js) * Version: 23.2.6 * Build date: Wed May 01 2024 * * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { getWidth, getOuterWidth, getHeight } from "../../core/utils/size"; import $ from "../../core/renderer"; import { isMaterial, isMaterialBased, waitWebFont } from "../themes"; import { isPlainObject, isDefined } from "../../core/utils/type"; import registerComponent from "../../core/component_registrator"; import { extend } from "../../core/utils/extend"; import { each } from "../../core/utils/iterator"; import { getBoundingRect } from "../../core/utils/position"; import AsyncCollectionWidget from "../collection/ui.collection_widget.async"; import { BindableTemplate } from "../../core/templates/bindable_template"; import fx from "../../animation/fx"; import { TOOLBAR_CLASS } from "./constants"; var TOOLBAR_BEFORE_CLASS = "dx-toolbar-before"; var TOOLBAR_CENTER_CLASS = "dx-toolbar-center"; var TOOLBAR_AFTER_CLASS = "dx-toolbar-after"; var TOOLBAR_MINI_CLASS = "dx-toolbar-mini"; var TOOLBAR_ITEM_CLASS = "dx-toolbar-item"; var TOOLBAR_LABEL_CLASS = "dx-toolbar-label"; var TOOLBAR_BUTTON_CLASS = "dx-toolbar-button"; var TOOLBAR_ITEMS_CONTAINER_CLASS = "dx-toolbar-items-container"; var TOOLBAR_GROUP_CLASS = "dx-toolbar-group"; var TOOLBAR_COMPACT_CLASS = "dx-toolbar-compact"; var TEXT_BUTTON_MODE = "text"; var DEFAULT_BUTTON_TYPE = "default"; var DEFAULT_DROPDOWNBUTTON_STYLING_MODE = "contained"; var TOOLBAR_ITEM_DATA_KEY = "dxToolbarItemDataKey"; var ANIMATION_TIMEOUT = 15; class ToolbarBase extends AsyncCollectionWidget { _getSynchronizableOptionsForCreateComponent() { return super._getSynchronizableOptionsForCreateComponent().filter(item => "disabled" !== item) } _initTemplates() { super._initTemplates(); var template = new BindableTemplate(function($container, data, rawModel) { if (isPlainObject(data)) { var { text: text, html: html, widget: widget } = data; if (text) { $container.text(text).wrapInner("<div>") } if (html) { $container.html(html) } if ("dxDropDownButton" === widget) { var _data$options; data.options = null !== (_data$options = data.options) && void 0 !== _data$options ? _data$options : {}; if (!isDefined(data.options.stylingMode)) { data.options.stylingMode = this.option("useFlatButtons") ? TEXT_BUTTON_MODE : DEFAULT_DROPDOWNBUTTON_STYLING_MODE } } if ("dxButton" === widget) { if (this.option("useFlatButtons")) { var _data$options2, _data$options$styling; data.options = null !== (_data$options2 = data.options) && void 0 !== _data$options2 ? _data$options2 : {}; data.options.stylingMode = null !== (_data$options$styling = data.options.stylingMode) && void 0 !== _data$options$styling ? _data$options$styling : TEXT_BUTTON_MODE } if (this.option("useDefaultButtons")) { var _data$options3, _data$options$type; data.options = null !== (_data$options3 = data.options) && void 0 !== _data$options3 ? _data$options3 : {}; data.options.type = null !== (_data$options$type = data.options.type) && void 0 !== _data$options$type ? _data$options$type : DEFAULT_BUTTON_TYPE } } } else { $container.text(String(data)) } this._getTemplate("dx-polymorph-widget").render({ container: $container, model: rawModel, parent: this }) }.bind(this), ["text", "html", "widget", "options"], this.option("integrationOptions.watchMethod")); this._templateManager.addDefaultTemplates({ item: template, menuItem: template }) } _getDefaultOptions() { return extend(super._getDefaultOptions(), { renderAs: "topToolbar", grouped: false, useFlatButtons: false, useDefaultButtons: false }) } _defaultOptionsRules() { return super._defaultOptionsRules().concat([{ device: function() { return isMaterialBased() }, options: { useFlatButtons: true } }]) } _itemContainer() { return this._$toolbarItemsContainer.find([".".concat(TOOLBAR_BEFORE_CLASS), ".".concat(TOOLBAR_CENTER_CLASS), ".".concat(TOOLBAR_AFTER_CLASS)].join(",")) } _itemClass() { return TOOLBAR_ITEM_CLASS } _itemDataKey() { return TOOLBAR_ITEM_DATA_KEY } _dimensionChanged() { if (this._disposed) { return } this._arrangeItems(); this._applyCompactMode() } _initMarkup() { this._renderToolbar(); this._renderSections(); super._initMarkup() } _render() { super._render(); this._renderItemsAsync(); this._updateDimensionsInMaterial() } _postProcessRenderItems() { this._arrangeItems() } _renderToolbar() { this.$element().addClass(TOOLBAR_CLASS); this._$toolbarItemsContainer = $("<div>").addClass(TOOLBAR_ITEMS_CONTAINER_CLASS).appendTo(this.$element()); this.setAria("role", "toolbar") } _renderSections() { var $container = this._$toolbarItemsContainer; each(["before", "center", "after"], (_, section) => { var sectionClass = "dx-toolbar-".concat(section); var $section = $container.find(".".concat(sectionClass)); if (!$section.length) { this["_$".concat(section, "Section")] = $("<div>").addClass(sectionClass).attr("role", "presentation").appendTo($container) } }) } _arrangeItems(elementWidth) { var _elementWidth; elementWidth = null !== (_elementWidth = elementWidth) && void 0 !== _elementWidth ? _elementWidth : getWidth(this.$element()); this._$centerSection.css({ margin: "0 auto", float: "none" }); var beforeRect = getBoundingRect(this._$beforeSection.get(0)); var afterRect = getBoundingRect(this._$afterSection.get(0)); this._alignCenterSection(beforeRect, afterRect, elementWidth); var $label = this._$toolbarItemsContainer.find(".".concat(TOOLBAR_LABEL_CLASS)).eq(0); var $section = $label.parent(); if (!$label.length) { return } var labelOffset = beforeRect.width ? beforeRect.width : $label.position().left; var widthBeforeSection = $section.hasClass(TOOLBAR_BEFORE_CLASS) ? 0 : labelOffset; var widthAfterSection = $section.hasClass(TOOLBAR_AFTER_CLASS) ? 0 : afterRect.width; var elemsAtSectionWidth = 0; $section.children().not(".".concat(TOOLBAR_LABEL_CLASS)).each((function() { elemsAtSectionWidth += getOuterWidth(this) })); var freeSpace = elementWidth - elemsAtSectionWidth; var sectionMaxWidth = Math.max(freeSpace - widthBeforeSection - widthAfterSection, 0); if ($section.hasClass(TOOLBAR_BEFORE_CLASS)) { this._alignSection(this._$beforeSection, sectionMaxWidth) } else { var labelPaddings = getOuterWidth($label) - getWidth($label); $label.css("maxWidth", sectionMaxWidth - labelPaddings) } } _alignCenterSection(beforeRect, afterRect, elementWidth) { this._alignSection(this._$centerSection, elementWidth - beforeRect.width - afterRect.width); var isRTL = this.option("rtlEnabled"); var leftRect = isRTL ? afterRect : beforeRect; var rightRect = isRTL ? beforeRect : afterRect; var centerRect = getBoundingRect(this._$centerSection.get(0)); if (leftRect.right > centerRect.left || centerRect.right > rightRect.left) { this._$centerSection.css({ marginLeft: leftRect.width, marginRight: rightRect.width, float: leftRect.width > rightRect.width ? "none" : "right" }) } } _alignSection($section, maxWidth) { var $labels = $section.find(".".concat(TOOLBAR_LABEL_CLASS)); var labels = $labels.toArray(); maxWidth -= this._getCurrentLabelsPaddings(labels); var currentWidth = this._getCurrentLabelsWidth(labels); var difference = Math.abs(currentWidth - maxWidth); if (maxWidth < currentWidth) { labels = labels.reverse(); this._alignSectionLabels(labels, difference, false) } else { this._alignSectionLabels(labels, difference, true) } } _alignSectionLabels(labels, difference, expanding) { var getRealLabelWidth = function(label) { return getBoundingRect(label).width }; for (var i = 0; i < labels.length; i++) { var $label = $(labels[i]); var currentLabelWidth = Math.ceil(getRealLabelWidth(labels[i])); var labelMaxWidth = void 0; if (expanding) { $label.css("maxWidth", "inherit") } var possibleLabelWidth = Math.ceil(expanding ? getRealLabelWidth(labels[i]) : currentLabelWidth); if (possibleLabelWidth < difference) { labelMaxWidth = expanding ? possibleLabelWidth : 0; difference -= possibleLabelWidth } else { labelMaxWidth = expanding ? currentLabelWidth + difference : currentLabelWidth - difference; $label.css("maxWidth", labelMaxWidth); break } $label.css("maxWidth", labelMaxWidth) } } _applyCompactMode() { var $element = this.$element(); $element.removeClass(TOOLBAR_COMPACT_CLASS); if (this.option("compactMode") && this._getSummaryItemsSize("width", this.itemElements(), true) > getWidth($element)) { $element.addClass(TOOLBAR_COMPACT_CLASS) } } _getCurrentLabelsWidth(labels) { var width = 0; labels.forEach((function(label, index) { width += getOuterWidth(label) })); return width } _getCurrentLabelsPaddings(labels) { var padding = 0; labels.forEach((function(label, index) { padding += getOuterWidth(label) - getWidth(label) })); return padding } _renderItem(index, item, itemContainer, $after) { var _item$location, _item$text; var location = null !== (_item$location = item.location) && void 0 !== _item$location ? _item$location : "center"; var container = null !== itemContainer && void 0 !== itemContainer ? itemContainer : this["_$".concat(location, "Section")]; var itemHasText = !!(null !== (_item$text = item.text) && void 0 !== _item$text ? _item$text : item.html); var itemElement = super._renderItem(index, item, container, $after); itemElement.toggleClass(TOOLBAR_BUTTON_CLASS, !itemHasText).toggleClass(TOOLBAR_LABEL_CLASS, itemHasText).addClass(item.cssClass); return itemElement } _renderGroupedItems() { each(this.option("items"), (groupIndex, group) => { var _group$location; var groupItems = group.items; var $container = $("<div>").addClass(TOOLBAR_GROUP_CLASS); var location = null !== (_group$location = group.location) && void 0 !== _group$location ? _group$location : "center"; if (!groupItems || !groupItems.length) { return } each(groupItems, (itemIndex, item) => { this._renderItem(itemIndex, item, $container, null) }); this._$toolbarItemsContainer.find(".dx-toolbar-".concat(location)).append($container) }) } _renderItems(items) { var grouped = this.option("grouped") && items.length && items[0].items; grouped ? this._renderGroupedItems() : super._renderItems(items) } _getToolbarItems() { var _this$option; return null !== (_this$option = this.option("items")) && void 0 !== _this$option ? _this$option : [] } _renderContentImpl() { var items = this._getToolbarItems(); this.$element().toggleClass(TOOLBAR_MINI_CLASS, 0 === items.length); if (this._renderedItemsCount) { this._renderItems(items.slice(this._renderedItemsCount)) } else { this._renderItems(items) } this._applyCompactMode() } _renderEmptyMessage() {} _clean() { this._$toolbarItemsContainer.children().empty(); this.$element().empty(); delete this._$beforeSection; delete this._$centerSection; delete this._$afterSection } _visibilityChanged(visible) { if (visible) { this._arrangeItems() } } _isVisible() { return getWidth(this.$element()) > 0 && getHeight(this.$element()) > 0 } _getIndexByItem(item) { return this._getToolbarItems().indexOf(item) } _itemOptionChanged(item, property, value) { super._itemOptionChanged.apply(this, [item, property, value]); this._arrangeItems() } _optionChanged(_ref) { var { name: name, value: value } = _ref; switch (name) { case "width": super._optionChanged.apply(this, arguments); this._dimensionChanged(); break; case "renderAs": case "useFlatButtons": case "useDefaultButtons": this._invalidate(); break; case "compactMode": this._applyCompactMode(); break; case "grouped": break; default: super._optionChanged.apply(this, arguments) } } _dispose() { super._dispose(); clearTimeout(this._waitParentAnimationTimeout) } _updateDimensionsInMaterial() { if (isMaterial()) { Promise.all([(() => new Promise(resolve => { var check = () => { var readyToResolve = true; this.$element().parents().each((_, parent) => { if (fx.isAnimating($(parent))) { readyToResolve = false; return false } }); if (readyToResolve) { resolve() } return readyToResolve }; var runCheck = () => { clearTimeout(this._waitParentAnimationTimeout); this._waitParentAnimationTimeout = setTimeout(() => check() || runCheck(), ANIMATION_TIMEOUT) }; runCheck() }))(), (() => { var $labels = this.$element().find(".".concat(TOOLBAR_LABEL_CLASS)); var promises = []; $labels.each((_, label) => { var text = $(label).text(); var fontWeight = $(label).css("fontWeight"); promises.push(waitWebFont(text, fontWeight)) }); return Promise.all(promises) })()]).then(() => { this._dimensionChanged() }) } } } registerComponent("dxToolbarBase", ToolbarBase); export default ToolbarBase;