UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

696 lines (684 loc) • 28.2 kB
/** * DevExtreme (renovation/viz/common/tooltip.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/ */ "use strict"; exports.Tooltip = exports.TooltipProps = exports.viewFunction = void 0; var _inferno = require("inferno"); var _vdom = require("@devextreme/vdom"); var _combine_classes = require("../../utils/combine_classes"); var _svg_path = require("./renderers/svg_path"); var _svg_text = require("./renderers/svg_text"); var _shadow_filter = require("./renderers/shadow_filter"); var _utils = require("./renderers/utils"); var _svg_root = require("./renderers/svg_root"); var _type = require("../../../core/utils/type"); var _tooltip_utils = require("./tooltip_utils"); var _utils2 = require("../../../viz/core/utils"); var _dom_adapter = _interopRequireDefault(require("../../../core/dom_adapter")); var _utils3 = require("./utils"); var _excluded = ["argumentFormat", "arrowLength", "arrowWidth", "border", "className", "color", "container", "contentTemplate", "cornerRadius", "customizeTooltip", "data", "enabled", "eventData", "font", "format", "interactive", "location", "offset", "onTooltipHidden", "onTooltipShown", "opacity", "paddingLeftRight", "paddingTopBottom", "rootWidget", "rtl", "shadow", "shared", "visible", "x", "y", "zIndex"]; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj } } function _objectWithoutProperties(source, excluded) { if (null == source) { return {} } var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) { continue } if (!Object.prototype.propertyIsEnumerable.call(source, key)) { continue } target[key] = source[key] } } return target } function _objectWithoutPropertiesLoose(source, excluded) { if (null == source) { return {} } var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) { continue } target[key] = source[key] } return target } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }) } else { obj[key] = value } return obj } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true } Object.defineProperty(target, descriptor.key, descriptor) } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) { _defineProperties(Constructor.prototype, protoProps) } if (staticProps) { _defineProperties(Constructor, staticProps) } return Constructor } function _assertThisInitialized(self) { if (void 0 === self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return self } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass) } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function(o, p) { o.__proto__ = p; return o }; return _setPrototypeOf(o, p) } function _extends() { _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key] } } } return target }; return _extends.apply(this, arguments) } var DEFAULT_CANVAS = { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0 }; var DEFAULT_FONT = { color: "#232323", family: "Segoe UI", opacity: 1, size: 12, weight: 400 }; var DEFAULT_SHADOW = { blur: 2, color: "#000", offsetX: 0, offsetY: 4, opacity: .4 }; var DEFAULT_BORDER = { color: "#d3d3d3", width: 1, dashStyle: "solid", visible: true }; var DEFAULT_SIZE = { x: 0, y: 0, width: 0, height: 0 }; var viewFunction = function(_ref) { var border = _ref.border, cloudRef = _ref.cloudRef, cloudSize = _ref.cloudSize, container = _ref.container, correctedCoordinates = _ref.correctedCoordinates, cssClassName = _ref.cssClassName, customizedOptions = _ref.customizedOptions, filterId = _ref.filterId, htmlRef = _ref.htmlRef, isEmptyContainer = _ref.isEmptyContainer, pointerEvents = _ref.pointerEvents, _ref$props = _ref.props, arrowWidth = _ref$props.arrowWidth, TooltipTemplate = _ref$props.contentTemplate, cornerRadius = _ref$props.cornerRadius, data = _ref$props.data, font = _ref$props.font, interactive = _ref$props.interactive, opacity = _ref$props.opacity, rtl = _ref$props.rtl, shadow = _ref$props.shadow, visible = _ref$props.visible, zIndex = _ref$props.zIndex, textRef = _ref.textRef, textSize = _ref.textSize, textSizeWithPaddings = _ref.textSizeWithPaddings; if (!visible || !correctedCoordinates || (0, _tooltip_utils.isTextEmpty)(customizedOptions) || isEmptyContainer) { return (0, _inferno.createVNode)(1, "div") } var angle = (0, _tooltip_utils.getCloudAngle)(textSizeWithPaddings, correctedCoordinates); var d = (0, _tooltip_utils.getCloudPoints)(textSizeWithPaddings, correctedCoordinates, angle, { cornerRadius: cornerRadius, arrowWidth: arrowWidth }, true); var styles = interactive ? { msUserSelect: "text", MozUserSelect: "auto", WebkitUserSelect: "auto" } : {}; styles = _extends({}, styles, { position: "absolute" }); return (0, _inferno.createComponentVNode)(2, _vdom.Portal, { container: container, children: (0, _inferno.createVNode)(1, "div", cssClassName, [(0, _inferno.createComponentVNode)(2, _svg_root.RootSvgElement, { width: cloudSize.width, height: cloudSize.height, styles: styles, children: [(0, _inferno.createVNode)(32, "defs", null, (0, _inferno.createComponentVNode)(2, _shadow_filter.ShadowFilter, { id: filterId, x: "-50%", y: "-50%", width: "200%", height: "200%", blur: shadow.blur, color: shadow.color, offsetX: shadow.offsetX, offsetY: shadow.offsetY, opacity: shadow.opacity }), 2), (0, _inferno.createVNode)(32, "g", null, [(0, _inferno.createComponentVNode)(2, _svg_path.PathSvgElement, { pointerEvents: pointerEvents, d: d, fill: customizedOptions.color, stroke: customizedOptions.borderColor, strokeWidth: border.strokeWidth, strokeOpacity: border.strokeOpacity, dashStyle: border.dashStyle, opacity: opacity, rotate: angle, rotateX: correctedCoordinates.x, rotateY: correctedCoordinates.y }), customizedOptions.html || TooltipTemplate ? null : (0, _inferno.createVNode)(32, "g", null, (0, _inferno.createComponentVNode)(2, _svg_text.TextSvgElement, { text: customizedOptions.text, styles: { fill: customizedOptions.fontColor, fontFamily: font.family, fontSize: font.size, fontWeight: font.weight, opacity: font.opacity, pointerEvents: pointerEvents } }), 2, { "text-anchor": "middle", transform: "translate(".concat(correctedCoordinates.x, ", ").concat(correctedCoordinates.y - textSize.height / 2 - textSize.y, ")") }, null, textRef)], 0, { filter: (0, _utils.getFuncIri)(filterId), transform: "translate(".concat(-cloudSize.x, ", ").concat(-cloudSize.y, ")") }, null, cloudRef)] }), !(customizedOptions.html || TooltipTemplate) ? null : (0, _inferno.createVNode)(1, "div", null, TooltipTemplate && TooltipTemplate(_extends({}, data)), 0, { style: (0, _vdom.normalizeStyles)({ position: "relative", display: "inline-block", left: correctedCoordinates.x - cloudSize.x - textSize.width / 2, top: correctedCoordinates.y - cloudSize.y - textSize.height / 2, fill: customizedOptions.fontColor, fontFamily: font.family, fontSize: font.size, fontWeight: font.weight, opacity: font.opacity, pointerEvents: pointerEvents, direction: rtl ? "rtl" : "ltr" }) }, null, htmlRef)], 0, { style: (0, _vdom.normalizeStyles)({ position: "absolute", pointerEvents: "none", left: cloudSize.x, top: cloudSize.y, zIndex: zIndex }) }) }) }; exports.viewFunction = viewFunction; var TooltipProps = { color: "#fff", border: DEFAULT_BORDER, data: {}, paddingLeftRight: 18, paddingTopBottom: 15, x: 0, y: 0, cornerRadius: 0, arrowWidth: 20, arrowLength: 10, offset: 0, font: DEFAULT_FONT, shadow: DEFAULT_SHADOW, interactive: false, enabled: true, shared: false, location: "center", visible: false, rtl: false }; exports.TooltipProps = TooltipProps; var getTemplate = function(TemplateProp) { return TemplateProp && (TemplateProp.defaultProps ? function(props) { return (0, _inferno.normalizeProps)((0, _inferno.createComponentVNode)(2, TemplateProp, _extends({}, props))) } : TemplateProp) }; var Tooltip = function(_InfernoComponent) { _inheritsLoose(Tooltip, _InfernoComponent); function Tooltip(props) { var _this; _this = _InfernoComponent.call(this, props) || this; _this._currentState = null; _this.cloudRef = (0, _inferno.createRef)(); _this.textRef = (0, _inferno.createRef)(); _this.htmlRef = (0, _inferno.createRef)(); _this.state = { filterId: (0, _utils.getNextDefsSvgId)(), textSize: DEFAULT_SIZE, cloudSize: DEFAULT_SIZE, currentEventData: void 0, isEmptyContainer: false, canvas: DEFAULT_CANVAS }; _this.setHtmlText = _this.setHtmlText.bind(_assertThisInitialized(_this)); _this.calculateSize = _this.calculateSize.bind(_assertThisInitialized(_this)); _this.eventsEffect = _this.eventsEffect.bind(_assertThisInitialized(_this)); _this.checkContainer = _this.checkContainer.bind(_assertThisInitialized(_this)); _this.setCanvas = _this.setCanvas.bind(_assertThisInitialized(_this)); _this.getLocation = _this.getLocation.bind(_assertThisInitialized(_this)); _this.calculateContentSize = _this.calculateContentSize.bind(_assertThisInitialized(_this)); _this.calculateCloudSize = _this.calculateCloudSize.bind(_assertThisInitialized(_this)); return _this } var _proto = Tooltip.prototype; _proto.createEffects = function() { var _this$props$rootWidge; return [new _vdom.InfernoEffect(this.setHtmlText, [this.props.border, this.props.color, this.props.customizeTooltip, this.props.data, this.props.font, this.props.visible]), new _vdom.InfernoEffect(this.calculateSize, [this.props.visible, this.props.x, this.props.y, this.textSize, this.cloudSize]), new _vdom.InfernoEffect(this.eventsEffect, [this.props.eventData, this.props.onTooltipHidden, this.props.onTooltipShown, this.props.visible, this.props.arrowLength, this.props.offset, this.props.x, this.props.y, this.canvas, this.props.paddingLeftRight, this.props.paddingTopBottom, this.textSize, this.currentEventData]), new _vdom.InfernoEffect(this.checkContainer, [this.props.visible]), new _vdom.InfernoEffect(this.setCanvas, [this.props.container, null === (_this$props$rootWidge = this.props.rootWidget) || void 0 === _this$props$rootWidge ? void 0 : _this$props$rootWidge.current])] }; _proto.updateEffects = function() { var _this$_effects$, _this$_effects$2, _this$_effects$3, _this$_effects$4, _this$_effects$5, _this$props$rootWidge2; null === (_this$_effects$ = this._effects[0]) || void 0 === _this$_effects$ ? void 0 : _this$_effects$.update([this.props.border, this.props.color, this.props.customizeTooltip, this.props.data, this.props.font, this.props.visible]); null === (_this$_effects$2 = this._effects[1]) || void 0 === _this$_effects$2 ? void 0 : _this$_effects$2.update([this.props.visible, this.props.x, this.props.y, this.textSize, this.cloudSize]); null === (_this$_effects$3 = this._effects[2]) || void 0 === _this$_effects$3 ? void 0 : _this$_effects$3.update([this.props.eventData, this.props.onTooltipHidden, this.props.onTooltipShown, this.props.visible, this.props.arrowLength, this.props.offset, this.props.x, this.props.y, this.canvas, this.props.paddingLeftRight, this.props.paddingTopBottom, this.textSize, this.currentEventData]); null === (_this$_effects$4 = this._effects[3]) || void 0 === _this$_effects$4 ? void 0 : _this$_effects$4.update([this.props.visible]); null === (_this$_effects$5 = this._effects[4]) || void 0 === _this$_effects$5 ? void 0 : _this$_effects$5.update([this.props.container, null === (_this$props$rootWidge2 = this.props.rootWidget) || void 0 === _this$props$rootWidge2 ? void 0 : _this$props$rootWidge2.current]) }; _proto.set_filterId = function(value) { var _this2 = this; this.setState((function(state) { _this2._currentState = state; var newValue = value(); _this2._currentState = null; return { filterId: newValue } })) }; _proto.set_textSize = function(value) { var _this3 = this; this.setState((function(state) { _this3._currentState = state; var newValue = value(); _this3._currentState = null; return { textSize: newValue } })) }; _proto.set_cloudSize = function(value) { var _this4 = this; this.setState((function(state) { _this4._currentState = state; var newValue = value(); _this4._currentState = null; return { cloudSize: newValue } })) }; _proto.set_currentEventData = function(value) { var _this5 = this; this.setState((function(state) { _this5._currentState = state; var newValue = value(); _this5._currentState = null; return { currentEventData: newValue } })) }; _proto.set_isEmptyContainer = function(value) { var _this6 = this; this.setState((function(state) { _this6._currentState = state; var newValue = value(); _this6._currentState = null; return { isEmptyContainer: newValue } })) }; _proto.set_canvas = function(value) { var _this7 = this; this.setState((function(state) { _this7._currentState = state; var newValue = value(); _this7._currentState = null; return { canvas: newValue } })) }; _proto.setHtmlText = function() { var htmlText = this.customizedOptions.html; if (htmlText && this.htmlRef.current && this.props.visible) { this.htmlRef.current.innerHTML = htmlText } }; _proto.calculateSize = function() { var contentSize = this.calculateContentSize(); var cloudSize = this.calculateCloudSize(); if ((0, _utils3.isUpdatedFlatObject)(this.textSize, contentSize)) { this.set_textSize((function() { return contentSize })) } if ((0, _utils3.isUpdatedFlatObject)(this.cloudSize, cloudSize)) { this.set_cloudSize((function() { return cloudSize })) } }; _proto.eventsEffect = function() { var _this$props = this.props, eventData = _this$props.eventData, onTooltipHidden = _this$props.onTooltipHidden, onTooltipShown = _this$props.onTooltipShown, visible = _this$props.visible; if (visible && this.correctedCoordinates && ! function(object1, object2) { if (!object1) { return false } return JSON.stringify(object1.target) === JSON.stringify(object2.target) }(this.currentEventData, eventData)) { this.currentEventData && (null === onTooltipHidden || void 0 === onTooltipHidden ? void 0 : onTooltipHidden(this.currentEventData)); null === onTooltipShown || void 0 === onTooltipShown ? void 0 : onTooltipShown(eventData); this.set_currentEventData((function() { return eventData })) } if (!visible && this.currentEventData) { null === onTooltipHidden || void 0 === onTooltipHidden ? void 0 : onTooltipHidden(this.currentEventData); this.set_currentEventData((function() { return })) } }; _proto.checkContainer = function() { if (this.htmlRef.current && this.props.visible) { var htmlTextSize = this.htmlRef.current.getBoundingClientRect(); if (!htmlTextSize.width && !htmlTextSize.height) { this.set_isEmptyContainer((function() { return true })) } } }; _proto.setCanvas = function() { var _this8 = this; this.set_canvas((function() { return (0, _tooltip_utils.getCanvas)(_this8.container) })) }; _proto.calculateContentSize = function() { var size = DEFAULT_SIZE; if (this.props.visible) { if (this.textRef.current) { size = this.textRef.current.getBBox() } else if (this.htmlRef.current) { size = this.htmlRef.current.getBoundingClientRect() } } return size }; _proto.calculateCloudSize = function() { var cloudSize = DEFAULT_SIZE; if ((0, _type.isDefined)(this.props.x) && (0, _type.isDefined)(this.props.y) && this.props.visible && this.cloudRef.current) { var size = this.cloudRef.current.getBBox(); var _this$margins = this.margins, bm = _this$margins.bm, lm = _this$margins.lm, rm = _this$margins.rm, tm = _this$margins.tm; cloudSize = { x: Math.floor(size.x - lm), y: Math.floor(size.y - tm), width: size.width + lm + rm, height: size.height + tm + bm } } return cloudSize }; _proto.getLocation = function() { return (0, _utils2.normalizeEnum)(this.props.location) }; _proto.render = function() { var props = this.props; return viewFunction({ props: _extends({}, props, { contentTemplate: getTemplate(props.contentTemplate) }), filterId: this.filterId, textSize: this.textSize, cloudSize: this.cloudSize, currentEventData: this.currentEventData, isEmptyContainer: this.isEmptyContainer, canvas: this.canvas, cloudRef: this.cloudRef, textRef: this.textRef, htmlRef: this.htmlRef, textSizeWithPaddings: this.textSizeWithPaddings, border: this.border, container: this.container, customizedOptions: this.customizedOptions, margins: this.margins, pointerEvents: this.pointerEvents, cssClassName: this.cssClassName, correctedCoordinates: this.correctedCoordinates, calculateContentSize: this.calculateContentSize, calculateCloudSize: this.calculateCloudSize, restAttributes: this.restAttributes }) }; _createClass(Tooltip, [{ key: "filterId", get: function() { var state = this._currentState || this.state; return state.filterId } }, { key: "textSize", get: function() { var state = this._currentState || this.state; return state.textSize } }, { key: "cloudSize", get: function() { var state = this._currentState || this.state; return state.cloudSize } }, { key: "currentEventData", get: function() { var state = this._currentState || this.state; return state.currentEventData } }, { key: "isEmptyContainer", get: function() { var state = this._currentState || this.state; return state.isEmptyContainer } }, { key: "canvas", get: function() { var state = this._currentState || this.state; return state.canvas } }, { key: "textSizeWithPaddings", get: function() { var _this$props2 = this.props, paddingLeftRight = _this$props2.paddingLeftRight, paddingTopBottom = _this$props2.paddingTopBottom; return { width: this.textSize.width + 2 * paddingLeftRight, height: this.textSize.height + 2 * paddingTopBottom } } }, { key: "border", get: function() { var border = this.props.border; if (border.visible) { return { stroke: border.color, strokeWidth: border.width, strokeOpacity: border.opacity, dashStyle: border.dashStyle } } return {} } }, { key: "container", get: function() { var propsContainer = this.props.container; if (propsContainer) { if ("string" === typeof propsContainer) { var _this$props$rootWidge3; var tmp = null === (_this$props$rootWidge3 = this.props.rootWidget) || void 0 === _this$props$rootWidge3 ? void 0 : _this$props$rootWidge3.current; var node = null === tmp || void 0 === tmp ? void 0 : tmp.closest(propsContainer); if (!node) { node = _dom_adapter.default.getDocument().querySelector(propsContainer) } if (node) { return node } } else { return propsContainer } } return _dom_adapter.default.getBody() } }, { key: "customizedOptions", get: function() { var _this$props3 = this.props, border = _this$props3.border, color = _this$props3.color, customizeTooltip = _this$props3.customizeTooltip, data = _this$props3.data, font = _this$props3.font; return (0, _tooltip_utils.prepareData)(data, color, border, font, customizeTooltip) } }, { key: "margins", get: function() { var max = Math.max; var shadow = this.props.shadow; var xOff = shadow.offsetX; var yOff = shadow.offsetY; var blur = 2 * shadow.blur + 1; return { lm: max(blur - xOff, 0), rm: max(blur + xOff, 0), tm: max(blur - yOff, 0), bm: max(blur + yOff, 0) } } }, { key: "pointerEvents", get: function() { var interactive = this.props.interactive; return interactive ? "auto" : "none" } }, { key: "cssClassName", get: function() { var className = this.props.className; var classesMap = _defineProperty({}, String(className), !!className); return (0, _combine_classes.combineClasses)(classesMap) } }, { key: "correctedCoordinates", get: function() { var _this$props4 = this.props, arrowLength = _this$props4.arrowLength, offset = _this$props4.offset, x = _this$props4.x, y = _this$props4.y; return (0, _tooltip_utils.recalculateCoordinates)({ canvas: this.canvas, anchorX: x, anchorY: y, size: this.textSizeWithPaddings, offset: offset, arrowLength: arrowLength }) } }, { key: "restAttributes", get: function() { var _this$props5 = this.props, restProps = (_this$props5.argumentFormat, _this$props5.arrowLength, _this$props5.arrowWidth, _this$props5.border, _this$props5.className, _this$props5.color, _this$props5.container, _this$props5.contentTemplate, _this$props5.cornerRadius, _this$props5.customizeTooltip, _this$props5.data, _this$props5.enabled, _this$props5.eventData, _this$props5.font, _this$props5.format, _this$props5.interactive, _this$props5.location, _this$props5.offset, _this$props5.onTooltipHidden, _this$props5.onTooltipShown, _this$props5.opacity, _this$props5.paddingLeftRight, _this$props5.paddingTopBottom, _this$props5.rootWidget, _this$props5.rtl, _this$props5.shadow, _this$props5.shared, _this$props5.visible, _this$props5.x, _this$props5.y, _this$props5.zIndex, _objectWithoutProperties(_this$props5, _excluded)); return restProps } }]); return Tooltip }(_vdom.InfernoComponent); exports.Tooltip = Tooltip; Tooltip.defaultProps = _extends({}, TooltipProps);