UNPKG

@uifabric/utilities

Version:

Fluent UI React utilities for building components.

240 lines 9.61 kB
import { __extends } from "tslib"; import * as React from 'react'; import { Async } from './Async'; import { EventGroup } from './EventGroup'; import { warnConditionallyRequiredProps } from './warn/warnConditionallyRequiredProps'; import { warnMutuallyExclusive } from './warn/warnMutuallyExclusive'; import { warnDeprecations } from './warn/warnDeprecations'; /** * BaseComponent class, which provides basic helpers for all components. * * @public * {@docCategory BaseComponent} * * @deprecated Do not use. We are moving away from class component. */ var BaseComponent = /** @class */ (function (_super) { __extends(BaseComponent, _super); /** * BaseComponent constructor * @param props - The props for the component. * @param context - The context for the component. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function BaseComponent(props, context) { var _this = _super.call(this, props, context) || this; // eslint-disable-next-line deprecation/deprecation _makeAllSafe(_this, BaseComponent.prototype, [ 'componentDidMount', 'shouldComponentUpdate', 'getSnapshotBeforeUpdate', 'render', 'componentDidUpdate', 'componentWillUnmount', ]); return _this; } /** * When the component receives props, make sure the componentRef is updated. */ BaseComponent.prototype.componentDidUpdate = function (prevProps, prevState) { this._updateComponentRef(prevProps, this.props); }; /** * When the component has mounted, update the componentRef. */ BaseComponent.prototype.componentDidMount = function () { this._setComponentRef(this.props.componentRef, this); }; /** * If we have disposables, dispose them automatically on unmount. */ BaseComponent.prototype.componentWillUnmount = function () { this._setComponentRef(this.props.componentRef, null); if (this.__disposables) { for (var i = 0, len = this._disposables.length; i < len; i++) { var disposable = this.__disposables[i]; if (disposable.dispose) { disposable.dispose(); } } this.__disposables = null; } }; Object.defineProperty(BaseComponent.prototype, "className", { /** * Gets the object's class name. */ get: function () { if (!this.__className) { var funcNameRegex = /function (.{1,})\(/; var results = funcNameRegex.exec(this.constructor.toString()); this.__className = results && results.length > 1 ? results[1] : ''; } return this.__className; }, enumerable: true, configurable: true }); Object.defineProperty(BaseComponent.prototype, "_disposables", { /** * Allows subclasses to push things to this._disposables to be auto disposed. */ get: function () { if (!this.__disposables) { this.__disposables = []; } return this.__disposables; }, enumerable: true, configurable: true }); Object.defineProperty(BaseComponent.prototype, "_async", { /** * Gets the async instance associated with the component, created on demand. The async instance gives * subclasses a way to execute setTimeout/setInterval async calls safely, where the callbacks * will be cleared/ignored automatically after unmounting. The helpers within the async object also * preserve the this pointer so that you don't need to "bind" the callbacks. */ get: function () { if (!this.__async) { this.__async = new Async(this); this._disposables.push(this.__async); } return this.__async; }, enumerable: true, configurable: true }); Object.defineProperty(BaseComponent.prototype, "_events", { /** * Gets the event group instance assocaited with the component, created on demand. The event instance * provides on/off methods for listening to DOM (or regular javascript object) events. The event callbacks * will be automatically disconnected after unmounting. The helpers within the events object also * preserve the this reference so that you don't need to "bind" the callbacks. */ get: function () { if (!this.__events) { this.__events = new EventGroup(this); this._disposables.push(this.__events); } return this.__events; }, enumerable: true, configurable: true }); /** * Helper to return a memoized ref resolver function. * @param refName - Name of the member to assign the ref to. * @returns A function instance keyed from the given refname. * @deprecated Use `createRef` from React.createRef. */ BaseComponent.prototype._resolveRef = function (refName) { var _this = this; if (!this.__resolves) { this.__resolves = {}; } if (!this.__resolves[refName]) { this.__resolves[refName] = function (ref) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (_this[refName] = ref); }; } return this.__resolves[refName]; }; /** * Updates the componentRef (by calling it with "this" when necessary.) */ BaseComponent.prototype._updateComponentRef = function (currentProps, newProps) { if (newProps === void 0) { newProps = {}; } // currentProps *should* always be defined, but verify that just in case a subclass is manually // calling a lifecycle method with no parameters (which has happened) or other odd usage. if (currentProps && newProps && currentProps.componentRef !== newProps.componentRef) { this._setComponentRef(currentProps.componentRef, null); this._setComponentRef(newProps.componentRef, this); } }; /** * Warns when a deprecated props are being used. * * @param deprecationMap - The map of deprecations, where key is the prop name and the value is * either null or a replacement prop name. */ BaseComponent.prototype._warnDeprecations = function (deprecationMap) { warnDeprecations(this.className, this.props, deprecationMap); }; /** * Warns when props which are mutually exclusive with each other are both used. * * @param mutuallyExclusiveMap - The map of mutually exclusive props. */ BaseComponent.prototype._warnMutuallyExclusive = function (mutuallyExclusiveMap) { warnMutuallyExclusive(this.className, this.props, mutuallyExclusiveMap); }; /** * Warns when props are required if a condition is met. * * @param requiredProps - The name of the props that are required when the condition is met. * @param conditionalPropName - The name of the prop that the condition is based on. * @param condition - Whether the condition is met. */ BaseComponent.prototype._warnConditionallyRequiredProps = function (requiredProps, conditionalPropName, condition) { warnConditionallyRequiredProps(this.className, this.props, requiredProps, conditionalPropName, condition); }; BaseComponent.prototype._setComponentRef = function (ref, value) { if (!this._skipComponentRefResolution && ref) { if (typeof ref === 'function') { ref(value); } if (typeof ref === 'object') { // eslint-disable-next-line @typescript-eslint/no-explicit-any ref.current = value; } } }; return BaseComponent; }(React.Component)); export { BaseComponent }; /** * Helper to override a given method with a wrapper method that can try/catch the original, but also * ensures that the BaseComponent's methods are called before the subclass's. This ensures that * componentWillUnmount in the base is called and that things in the _disposables array are disposed. */ // eslint-disable-next-line deprecation/deprecation function _makeAllSafe(obj, prototype, methodNames) { for (var i = 0, len = methodNames.length; i < len; i++) { _makeSafe(obj, prototype, methodNames[i]); } } // eslint-disable-next-line deprecation/deprecation function _makeSafe(obj, prototype, methodName) { /* eslint-disable @typescript-eslint/no-explicit-any */ var classMethod = obj[methodName]; var prototypeMethod = prototype[methodName]; if (classMethod || prototypeMethod) { obj[methodName] = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } /* eslint-enable @typescript-eslint/no-explicit-any */ var retVal; if (prototypeMethod) { retVal = prototypeMethod.apply(this, args); } if (classMethod !== prototypeMethod) { retVal = classMethod.apply(this, args); } return retVal; }; } } /** * Simple constant function for returning null, used to render empty templates in JSX. * * @public */ export function nullRender() { return null; } //# sourceMappingURL=BaseComponent.js.map