UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

176 lines • 9.63 kB
define(["require", "exports", "tslib", "react", "../../Utilities", "../../Styling", "./PositioningContainer/PositioningContainer", "./Beak/Beak", "./Coachmark.styles", "../../FocusZone"], function (require, exports, tslib_1, React, Utilities_1, Styling_1, PositioningContainer_1, Beak_1, Coachmark_styles_1, FocusZone_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var getClassNames = Utilities_1.classNamesFunction(); var Coachmark = /** @class */ (function (_super) { tslib_1.__extends(Coachmark, _super); function Coachmark(props) { var _this = _super.call(this, props) || this; // Set defaults for state _this.state = { collapsed: props.collapsed, isBeaconAnimating: true, isMeasuring: true, entityInnerHostRect: { width: 0, height: 0 }, isMouseInProximity: false }; return _this; } Coachmark.prototype.render = function () { var _a = this.props, children = _a.children, beakWidth = _a.beakWidth, beakHeight = _a.beakHeight, target = _a.target, width = _a.width, height = _a.height, color = _a.color, beaconColorOne = _a.beaconColorOne, beaconColorTwo = _a.beaconColorTwo; var classNames = getClassNames(Coachmark_styles_1.getStyles, { collapsed: this.state.collapsed, isBeaconAnimating: this.state.isBeaconAnimating, isMeasuring: this.state.isMeasuring, entityHostHeight: this.state.entityInnerHostRect.height + 'px', entityHostWidth: this.state.entityInnerHostRect.width + 'px', width: width + 'px', height: height + 'px', color: color, beaconColorOne: beaconColorOne, beaconColorTwo: beaconColorTwo }); return (React.createElement(PositioningContainer_1.PositioningContainer, { target: target, offsetFromTarget: beakHeight, componentRef: this._resolveRef('_positioningContainer') }, React.createElement("div", { className: classNames.root }, React.createElement("div", { className: classNames.pulsingBeacon }), React.createElement("div", { className: classNames.translateAnimationContainer, ref: this._resolveRef('_translateAnimationContainer') }, React.createElement("div", { className: classNames.scaleAnimationLayer }, React.createElement("div", { className: classNames.rotateAnimationLayer }, this._positioningContainer && React.createElement(Beak_1.Beak, { width: beakWidth, height: beakHeight, left: this.state.beakLeft, top: this.state.beakTop }), React.createElement(FocusZone_1.FocusZone, null, React.createElement("div", { className: classNames.entityHost, ref: this._resolveRef('_entityHost'), "data-is-focusable": true, onFocus: this._onFocusHandler }, React.createElement("div", { className: classNames.entityInnerHost, ref: this._resolveRef('_entityInnerHostElement') }, children))))))))); }; Coachmark.prototype.componentWillReceiveProps = function (newProps) { if (this.props.collapsed && !newProps.collapsed) { // The coachmark is about to open this._openCoachmark(); } }; Coachmark.prototype.componentDidMount = function () { var _this = this; this._async.requestAnimationFrame((function () { if ((_this.state.entityInnerHostRect.width + _this.state.entityInnerHostRect.width) === 0) { // @TODO Eventually we need to add the various directions var beakLeft = (_this.props.width / 2) - (_this.props.beakWidth / 2); var beakTop = 0; _this.setState({ isMeasuring: false, entityInnerHostRect: { width: _this._entityInnerHostElement.offsetWidth, height: _this._entityInnerHostElement.offsetHeight }, beakLeft: beakLeft + 'px', beakTop: beakTop + 'px' }); _this.forceUpdate(); } // We dont want to the user to immediatley trigger the coachmark when it's opened _this._async.setTimeout(function () { _this._addProximityHandler(100); }, _this.props.delayBeforeMouseOpen); })); }; Coachmark.prototype._onFocusHandler = function () { this._openCoachmark(); }; Coachmark.prototype._openCoachmark = function () { var _this = this; this.setState({ collapsed: false }); this._translateAnimationContainer.addEventListener('animationstart', function () { if (_this.props.onAnimationOpenStart) { _this.props.onAnimationOpenStart(); } }); this._translateAnimationContainer.addEventListener('animationend', function () { if (_this.props.onAnimationOpenEnd) { _this.props.onAnimationOpenEnd(); } }); }; Coachmark.prototype._addProximityHandler = function (mouseProximityOffset) { var _this = this; if (mouseProximityOffset === void 0) { mouseProximityOffset = 0; } /** * An array of cached ids returned when setTimeout runs during * the window resize event trigger. */ var timeoutIds = []; /** * The target element the mouse would be in * proximity to */ var targetElementRect; // Take the initial measure out of the initial render to prevent // an unnessecary render. this._async.setTimeout(function () { targetElementRect = _this._entityInnerHostElement.getBoundingClientRect(); // When the window resizes we want to async // get the bounding client rectangle. // Every time the event is triggered we want to // setTimeout and then clear any previous instances // of setTimeout. _this._events.on(window, 'resize', function () { timeoutIds.forEach(function (value) { clearInterval(value); }); timeoutIds.push(_this._async.setTimeout(function () { targetElementRect = _this._entityInnerHostElement.getBoundingClientRect(); }, 100)); }); }, 10); // Every time the document's mouse move is triggered // we want to check if inside of an element and // set the state with the result. this._events.on(document, 'mousemove', function (e) { var mouseY = e.pageY; var mouseX = e.pageX; var isMouseInProximity = _this._isInsideElement(mouseX, mouseY, targetElementRect, mouseProximityOffset); if (isMouseInProximity !== _this.state.isMouseInProximity) { // We don't want to update the isMouseInProximtiy state because // The coachmark only opens and does not collapse. // Setting isMouseInProximity here will cause the coachmark to open and close _this.setState({ collapsed: !isMouseInProximity }); } if (_this.props.onMouseMove) { _this.props.onMouseMove(e); } }); }; Coachmark.prototype._isInsideElement = function (mouseX, mouseY, elementRect, mouseProximityOffset) { if (mouseProximityOffset === void 0) { mouseProximityOffset = 0; } return mouseX > (elementRect.left - mouseProximityOffset) && mouseX < ((elementRect.left + elementRect.width) + mouseProximityOffset) && mouseY > (elementRect.top - mouseProximityOffset) && mouseY < ((elementRect.top + elementRect.height) + mouseProximityOffset); }; Coachmark.defaultProps = { collapsed: true, mouseProximityOffset: 100, beakWidth: 26, beakHeight: 12, delayBeforeMouseOpen: 3600, width: 36, height: 36, beaconColorOne: '#00FFEC', beaconColorTwo: '#005EDD', color: Styling_1.DefaultPalette.themePrimary }; tslib_1.__decorate([ Utilities_1.autobind ], Coachmark.prototype, "_onFocusHandler", null); tslib_1.__decorate([ Utilities_1.autobind ], Coachmark.prototype, "_openCoachmark", null); return Coachmark; }(Utilities_1.BaseComponent)); exports.Coachmark = Coachmark; }); //# sourceMappingURL=Coachmark.js.map