devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
328 lines (327 loc) • 13 kB
JavaScript
/**
* DevExtreme (esm/ui/speed_dial_action/speed_dial_main_item.js)
* Version: 21.1.4
* Build date: Mon Jun 21 2021
*
* Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import $ from "../../core/renderer";
import config from "../../core/config";
import {
extend
} from "../../core/utils/extend";
import eventsEngine from "../../events/core/events_engine";
import errors from "../widget/ui.errors";
import swatchContainer from "../widget/swatch_container";
import SpeedDialItem from "./speed_dial_item";
import {
isMaterial
} from "../themes";
var {
getSwatchContainer: getSwatchContainer
} = swatchContainer;
var FAB_MAIN_CLASS = "dx-fa-button-main";
var FAB_MAIN_CLASS_WITH_LABEL = "dx-fa-button-with-label";
var FAB_CLOSE_ICON_CLASS = "dx-fa-button-icon-close";
var INVISIBLE_STATE_CLASS = "dx-state-invisible";
var speedDialMainItem = null;
var modifyActionOptions = action => extend({}, action._options.silent(), {
onInitialized: null,
onDisposing: null
});
class SpeedDialMainItem extends SpeedDialItem {
_getDefaultOptions() {
return extend(super._getDefaultOptions(), extend({
icon: "add",
closeIcon: "close",
position: {
at: "right bottom",
my: "right bottom",
offset: {
x: -16,
y: -16
}
},
maxSpeedDialActionCount: 5,
hint: "",
label: "",
direction: "auto",
actions: [],
activeStateEnabled: true,
hoverStateEnabled: true,
indent: 55,
childIndent: 40,
childOffset: 9,
callOverlayRenderShading: true,
closeOnOutsideClick: true
}, config().floatingActionButtonConfig, {
shading: false
}))
}
_defaultOptionsRules() {
return super._defaultOptionsRules().concat([{
device: () => isMaterial(),
options: {
indent: 72,
childIndent: 56,
childOffset: 8
}
}])
}
_render() {
this.$element().addClass(FAB_MAIN_CLASS);
super._render();
this._moveToContainer();
this._renderCloseIcon();
this._renderClick()
}
_renderLabel() {
super._renderLabel();
this.$element().toggleClass(FAB_MAIN_CLASS_WITH_LABEL, !!this._$label)
}
_renderCloseIcon() {
this._$closeIcon = this._renderButtonIcon(this._$closeIcon, this._options.silent("closeIcon"), FAB_CLOSE_ICON_CLASS);
this._$closeIcon.addClass(INVISIBLE_STATE_CLASS)
}
_renderClick() {
this._clickAction = 1 === this._getVisibleActions().length ? this._getActionComponent()._createActionByOption("onClick") : this._createAction(this._clickHandler.bind(this));
this._setClickAction()
}
_getVisibleActions(actions) {
var currentActions = actions || this.option("actions");
return currentActions.filter(action => action.option("visible"))
}
_getCurrentOptions(actions) {
var visibleActions = speedDialMainItem._getVisibleActions(actions);
return 1 === visibleActions.length ? extend(visibleActions[0]._options.silent(), {
position: this._getPosition()
}) : extend(this._getDefaultOptions(), {
visible: 0 !== visibleActions.length
})
}
_clickHandler() {
var actions = this._actionItems.filter(action => action.option("actionVisible")).sort((action, nextAction) => action.option("index") - nextAction.option("index"));
if (1 === actions.length) {
return
}
var lastActionIndex = actions.length - 1;
for (var i = 0; i < actions.length; i++) {
actions[i].option("animation", this._getActionAnimation(actions[i], i, lastActionIndex));
actions[i].option("position", this._getActionPosition(actions, i));
actions[i]._$wrapper.css("position", this._$wrapper.css("position"));
actions[i].toggle()
}
if (config().floatingActionButtonConfig.shading) {
this._isShadingShown = !this.option("shading");
this.option("shading", this._isShadingShown)
}
this._$icon.toggleClass(INVISIBLE_STATE_CLASS);
this._$closeIcon.toggleClass(INVISIBLE_STATE_CLASS)
}
_updateZIndexStackPosition() {
super._updateZIndexStackPosition();
var overlayStack = this._overlayStack();
overlayStack.push(this)
}
_renderActions() {
var actions = this.option("actions");
if (this._actionItems && this._actionItems.length) {
this._actionItems.forEach(actionItem => {
actionItem.dispose();
actionItem.$element().remove()
});
this._actionItems = []
}
this._actionItems = [];
if (1 === actions.length) {
return
}
for (var i = 0; i < actions.length; i++) {
var action = actions[i];
var $actionElement = $("<div>").appendTo(getSwatchContainer(action.$element()));
eventsEngine.off($actionElement, "click");
eventsEngine.on($actionElement, "click", () => {
this._clickHandler()
});
action._options.silent("actionComponent", action);
action._options.silent("parentPosition", this._getPosition());
action._options.silent("actionVisible", action._options.silent("visible"));
this._actionItems.push(this._createComponent($actionElement, SpeedDialItem, extend({}, modifyActionOptions(action), {
visible: false
})))
}
}
_getActionAnimation(action, index, lastActionIndex) {
action._options.silent("animation.show.delay", 30 * index);
action._options.silent("animation.hide.delay", 30 * (lastActionIndex - index));
return action._options.silent("animation")
}
_getDirectionIndex(actions, direction) {
if ("auto" === direction) {
var contentHeight = this.$content().height();
var actionsHeight = this.initialOption("indent") + this.initialOption("childIndent") * actions.length - contentHeight;
var offsetTop = this.$content().offset().top;
if (actionsHeight < offsetTop) {
return -1
} else {
var offsetBottom = this._getContainer().height() - contentHeight - offsetTop;
return offsetTop >= offsetBottom ? -1 : 1
}
}
return "down" !== direction ? -1 : 1
}
_getActionPosition(actions, index) {
var action = actions[index];
var actionOffsetXValue = this.initialOption("childOffset");
var actionOffsetX = action._options.silent("label") && !this._$label ? this._isPositionLeft(this._getPosition()) ? actionOffsetXValue : -actionOffsetXValue : 0;
var actionOffsetYValue = this.initialOption("indent") + this.initialOption("childIndent") * index;
var actionOffsetY = this._getDirectionIndex(actions, this.option("direction")) * actionOffsetYValue;
var actionPositionAtMy = action._options.silent("label") ? this._isPositionLeft(this._getPosition()) ? "left" : "right" : "center";
return {
of: this.$content(),
at: actionPositionAtMy,
my: actionPositionAtMy,
offset: {
x: actionOffsetX,
y: actionOffsetY
}
}
}
_outsideClickHandler(e) {
if (this._isShadingShown) {
var isShadingClick = $(e.target)[0] === this._$wrapper[0];
if (isShadingClick) {
e.preventDefault();
this._clickHandler()
}
}
}
_setPosition() {
if (this.option("visible")) {
this._hide();
this._show()
}
}
_getPosition() {
return this._getDefaultOptions().position
}
_getInkRippleContainer() {
return this.$content()
}
_optionChanged(args) {
switch (args.name) {
case "actions":
if (this._isVisible()) {
this._renderIcon();
this._renderLabel()
}
this._renderCloseIcon();
this._renderClick();
this._renderActions();
break;
case "maxSpeedDialActionCount":
this._renderActions();
break;
case "closeIcon":
this._renderCloseIcon();
break;
case "position":
this._setPosition();
break;
case "label":
if (this._isVisible()) {
this._renderLabel()
}
this._setPosition();
break;
case "icon":
if (this._isVisible()) {
this._renderIcon()
}
break;
default:
super._optionChanged(args)
}
}
}
export function initAction(newAction) {
newAction._options.silent("onInitializing", null);
var isActionExist = false;
if (!speedDialMainItem) {
var $fabMainElement = $("<div>").appendTo(getSwatchContainer(newAction.$element()));
speedDialMainItem = newAction._createComponent($fabMainElement, SpeedDialMainItem, extend({}, modifyActionOptions(newAction), {
actions: [newAction]
}))
} else {
var savedActions = speedDialMainItem.option("actions");
savedActions.forEach(action => {
if (action._options.silent("id") === newAction._options.silent("id")) {
isActionExist = true;
return newAction
}
});
speedDialMainItem._options.silent("position"), true;
if (!isActionExist) {
if (speedDialMainItem._getVisibleActions(savedActions).length >= speedDialMainItem.option("maxSpeedDialActionCount")) {
newAction.dispose();
errors.log("W1014");
return
}
savedActions.push(newAction);
speedDialMainItem.option(extend(speedDialMainItem._getCurrentOptions(savedActions), {
actions: savedActions
}))
} else if (1 === savedActions.length) {
speedDialMainItem.option(extend({}, modifyActionOptions(savedActions[0]), {
actions: savedActions,
position: speedDialMainItem._getPosition()
}))
} else {
speedDialMainItem.option(extend(speedDialMainItem._getCurrentOptions(savedActions), {
actions: savedActions
}))
}
}
}
export function disposeAction(actionId) {
if (!speedDialMainItem) {
return
}
var savedActions = speedDialMainItem.option("actions");
var savedActionsCount = savedActions.length;
savedActions = savedActions.filter(action => action._options.silent("id") !== actionId);
if (savedActionsCount === savedActions.length) {
return
}
if (!savedActions.length) {
speedDialMainItem.dispose();
speedDialMainItem.$element().remove();
speedDialMainItem = null
} else if (1 === savedActions.length) {
speedDialMainItem.option(extend({}, modifyActionOptions(savedActions[0]), {
actions: savedActions
}))
} else {
speedDialMainItem.option({
actions: savedActions
})
}
}
export function repaint() {
if (!speedDialMainItem) {
return
}
var visibleActions = speedDialMainItem._getVisibleActions();
var icon = 1 === visibleActions.length ? visibleActions[0].option("icon") : speedDialMainItem._getDefaultOptions().icon;
var label = 1 === visibleActions.length ? visibleActions[0].option("label") : speedDialMainItem._getDefaultOptions().label;
speedDialMainItem.option({
actions: speedDialMainItem.option("actions"),
icon: icon,
closeIcon: speedDialMainItem._getDefaultOptions().closeIcon,
position: speedDialMainItem._getPosition(),
label: label,
maxSpeedDialActionCount: speedDialMainItem._getDefaultOptions().maxSpeedDialActionCount,
direction: speedDialMainItem._getDefaultOptions().direction
})
}