UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

182 lines (181 loc) 9.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.config = exports.getDirection = exports.getLanguage = exports.getLocale = exports.setDirection = exports.setLocale = exports.setLanguage = exports.initLocales = void 0; var tslib_1 = require("tslib"); var react_1 = tslib_1.__importDefault(require("react")); var prop_types_1 = tslib_1.__importDefault(require("prop-types")); var hoist_non_react_statics_1 = tslib_1.__importDefault(require("hoist-non-react-statics")); var util_1 = require("../util"); var get_context_props_1 = tslib_1.__importDefault(require("./get-context-props")); var error_boundary_1 = tslib_1.__importDefault(require("./error-boundary")); var shallowEqual = util_1.obj.shallowEqual; function getDisplayName(Component) { return Component.displayName || Component.name || 'Component'; } var globalLocales; var currentGlobalLanguage = 'zh-cn'; var currentGlobalLocale = {}; var currentGlobalRtl; function initLocales(locales) { globalLocales = locales; if (locales) { currentGlobalLocale = locales[currentGlobalLanguage]; if (typeof currentGlobalRtl !== 'boolean') { currentGlobalRtl = currentGlobalLocale && currentGlobalLocale.rtl; } } } exports.initLocales = initLocales; function setLanguage(language) { if (globalLocales) { currentGlobalLanguage = language; currentGlobalLocale = globalLocales[language]; if (typeof currentGlobalRtl !== 'boolean') { currentGlobalRtl = currentGlobalLocale && currentGlobalLocale.rtl; } } } exports.setLanguage = setLanguage; function setLocale(locale) { currentGlobalLocale = tslib_1.__assign(tslib_1.__assign({}, (globalLocales ? globalLocales[currentGlobalLanguage] : {})), locale); if (typeof currentGlobalRtl !== 'boolean') { currentGlobalRtl = currentGlobalLocale && currentGlobalLocale.rtl; } } exports.setLocale = setLocale; function setDirection(dir) { currentGlobalRtl = dir === 'rtl'; } exports.setDirection = setDirection; function getLocale() { return currentGlobalLocale; } exports.getLocale = getLocale; function getLanguage() { return currentGlobalLanguage; } exports.getLanguage = getLanguage; function getDirection() { return currentGlobalRtl; } exports.getDirection = getDirection; function isCanPassRefComponent(component) { return util_1.obj.isClassComponent(component) || util_1.obj.isForwardRefComponent(component); } function config(Component, options) { if (options === void 0) { options = {}; } // 非 forwardRef 创建的 class component if (util_1.obj.isClassComponent(Component) && Component.prototype.shouldComponentUpdate === undefined) { // class component: 通过定义 shouldComponentUpdate 改写成 pure component, 有 refs Component.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { if (this.props.pure) { return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); } return true; }; } var ConfigedComponent = /** @class */ (function (_super) { tslib_1.__extends(ConfigedComponent, _super); function ConfigedComponent(props, context) { var _this = _super.call(this, props, context) || this; _this._getInstance = _this._getInstance.bind(_this); _this._deprecated = _this._deprecated.bind(_this); return _this; } ConfigedComponent.prototype._getInstance = function (ref) { var _this = this; this._instance = ref; if (this._instance && options.exportNames) { options.exportNames.forEach(function (name) { var field = _this._instance[name]; if (typeof field === 'function') { _this[name] = field.bind(_this._instance); } else { _this[name] = field; } }); } }; ConfigedComponent.prototype._deprecated = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.context.nextWarning !== false) { util_1.log.deprecated.apply(util_1.log, tslib_1.__spreadArray([], tslib_1.__read(args), false)); } }; ConfigedComponent.prototype.getInstance = function () { return this._instance; }; ConfigedComponent.prototype.render = function () { var _a = this.props, prefix = _a.prefix, locale = _a.locale, // fixme: defaultPropsConfig is unused defaultPropsConfig = _a.defaultPropsConfig, pure = _a.pure, rtl = _a.rtl, device = _a.device, popupContainer = _a.popupContainer, errorBoundary = _a.errorBoundary, others = tslib_1.__rest(_a, ["prefix", "locale", "defaultPropsConfig", "pure", "rtl", "device", "popupContainer", "errorBoundary"]); var _b = this.context, nextPrefix = _b.nextPrefix, _c = _b.nextLocale, nextLocale = _c === void 0 ? {} : _c, _d = _b.nextDefaultPropsConfig, nextDefaultPropsConfig = _d === void 0 ? {} : _d, nextPure = _b.nextPure, nextRtl = _b.nextRtl, nextDevice = _b.nextDevice, nextPopupContainer = _b.nextPopupContainer, nextErrorBoundary = _b.nextErrorBoundary; var displayName = options.componentName || getDisplayName(Component); var contextProps = (0, get_context_props_1.default)({ prefix: prefix, locale: locale, defaultPropsConfig: defaultPropsConfig, pure: pure, device: device, popupContainer: popupContainer, rtl: rtl, errorBoundary: errorBoundary, }, { nextPrefix: nextPrefix, nextLocale: tslib_1.__assign(tslib_1.__assign({}, currentGlobalLocale), nextLocale), nextDefaultPropsConfig: nextDefaultPropsConfig, nextPure: nextPure, nextDevice: nextDevice, nextPopupContainer: nextPopupContainer, nextRtl: typeof nextRtl === 'boolean' ? nextRtl : currentGlobalRtl === true ? true : undefined, nextErrorBoundary: nextErrorBoundary, }, displayName); // errorBoundary is only for <ErrorBoundary> var newContextProps = ['prefix', 'locale', 'pure', 'rtl', 'device', 'popupContainer'].reduce(function (ret, name) { if (typeof contextProps[name] !== 'undefined') { // @ts-expect-error ignore assign type error ret[name] = contextProps[name]; } return ret; }, {}); if ('pure' in newContextProps && newContextProps.pure) { util_1.log.warning('pure of ConfigProvider is deprecated, use Function Component or React.PureComponent'); } // 对于两个真正消费 popupContainer 的组件来说,正确的名字是 container, if ('popupContainer' in newContextProps && this.props.container === undefined && ['Overlay', 'Popup'].indexOf(displayName) > -1) { newContextProps.container = newContextProps.popupContainer; delete newContextProps.popupContainer; } var newOthers = options.transform ? options.transform(others, this._deprecated) : others; var newProps = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, contextProps.defaultPropsConfig[displayName]), newOthers), newContextProps); // 仅向 class or forwardRef component 传递 ref,否则 react 会报一个 warning if (isCanPassRefComponent(Component)) { newProps.ref = this._getInstance; } var content = react_1.default.createElement(Component, tslib_1.__assign({}, newProps)); var _e = contextProps.errorBoundary, open = _e.open, othersBoundary = tslib_1.__rest(_e, ["open"]); return open ? react_1.default.createElement(error_boundary_1.default, tslib_1.__assign({}, othersBoundary), content) : content; }; ConfigedComponent.displayName = "Config(".concat(getDisplayName(Component), ")"); ConfigedComponent.propTypes = tslib_1.__assign(tslib_1.__assign({}, (Component.propTypes || {})), { prefix: prop_types_1.default.string, locale: prop_types_1.default.object, defaultPropsConfig: prop_types_1.default.object, pure: prop_types_1.default.bool, rtl: prop_types_1.default.bool, device: prop_types_1.default.oneOf(['tablet', 'desktop', 'phone']), popupContainer: prop_types_1.default.any, errorBoundary: prop_types_1.default.oneOfType([prop_types_1.default.bool, prop_types_1.default.object]) }); ConfigedComponent.contextTypes = tslib_1.__assign(tslib_1.__assign({}, (Component.contextTypes || {})), { nextPrefix: prop_types_1.default.string, nextLocale: prop_types_1.default.object, nextDefaultPropsConfig: prop_types_1.default.object, nextPure: prop_types_1.default.bool, nextRtl: prop_types_1.default.bool, nextWarning: prop_types_1.default.bool, nextDevice: prop_types_1.default.oneOf(['tablet', 'desktop', 'phone']), nextPopupContainer: prop_types_1.default.any, nextErrorBoundary: prop_types_1.default.oneOfType([prop_types_1.default.bool, prop_types_1.default.object]) }); return ConfigedComponent; }(react_1.default.Component)); (0, hoist_non_react_statics_1.default)(ConfigedComponent, Component); // 这里将 ConfigedComponent 推断一个限定的类型,以简化生成的类型代码 return ConfigedComponent; } exports.config = config;