devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
404 lines (403 loc) • 16.6 kB
JavaScript
/**
* 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;