UNPKG

react-elegant-ui

Version:

Elegant UI components, made by BEM best practices for react

169 lines 5.59 kB
// Imported from @bem-react/di. Source: https://github.com/bem/bem-react/blob/master/packages/di/di.tsx // This file forked from https://github.com/bem/bem-react/blob/95cb27909cc232d3676b4d010b5b9b8cf171e8e3/packages/di/di.tsx // Reason: no maintenance // Original contributors: @yarastqt @awinogradov @Vittly @isqua @artems var __assign = this && this.__assign || function () { __assign = Object.assign || function (t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import React, { createContext, useContext, useRef, createElement } from 'react'; export var registryContext = /*#__PURE__*/createContext({}); var RegistriesConsumer = registryContext.Consumer; var RegistryProvider = registryContext.Provider; export function withRegistry() { // Use arguments instead of rest-arguments to get faster and more compact code. var registries = [].slice.call(arguments); return function WithRegistry(Component) { var RegistryResolver = function (props) { var providedRegistriesRef = useRef(null); return /*#__PURE__*/React.createElement(RegistriesConsumer, null, function (contextRegistries) { if (providedRegistriesRef.current === null) { var providedRegistries = __assign({}, contextRegistries); for (var i = 0; i < registries.length; i++) { var registry = registries[i]; var overrides = providedRegistries[registry.id]; // eslint-disable-next-line no-nested-ternary providedRegistries[registry.id] = registry.overridable ? overrides ? registry.merge(overrides) : registry : registry && overrides ? overrides.merge(registry) : registry; } providedRegistriesRef.current = providedRegistries; } return /*#__PURE__*/React.createElement(RegistryProvider, { value: providedRegistriesRef.current }, /*#__PURE__*/createElement(Component, props)); }); }; return RegistryResolver; }; } export var RegistryConsumer = function (props) { return /*#__PURE__*/React.createElement(RegistriesConsumer, null, function (registries) { return props.children(registries[props.id].snapshot()); }); }; /** * @deprecated consider using 'RegistryConsumer' instead */ export var ComponentRegistryConsumer = RegistryConsumer; export var useRegistries = function () { return useContext(registryContext); }; export var useRegistry = function (id) { var registries = useRegistries(); return registries[id].snapshot(); }; /** * @deprecated consider using 'useRegistry' instead */ export var useComponentRegistry = useRegistry; var registryOverloadMark = 'RegistryOverloadHMark'; function withOverload(overload) { return { $symbol: registryOverloadMark, overload: overload }; } function isOverload(entity) { return entity.$symbol === registryOverloadMark; } var Registry = /** @class */function () { function Registry(_a) { var id = _a.id, _b = _a.overridable, overridable = _b === void 0 ? true : _b; this.entities = {}; this.id = id; this.overridable = overridable; } /** * Set registry entry by id. * * @param id entry id * @param entity valid registry entity */ Registry.prototype.set = function (id, entity) { this.entities[id] = entity; return this; }; /** * Set extender for registry entry by id. * * @param id entry id * @param overload valid registry entity extender */ Registry.prototype.extends = function (id, overload) { this.entities[id] = withOverload(overload); return this; }; /** * Set react entities in registry via object literal. * * @param entitiesSet set of valid registry entities */ Registry.prototype.fill = function (entitiesSet) { for (var key in entitiesSet) { this.entities[key] = entitiesSet[key]; } return this; }; /** * Get entry from registry by id. * * @param id entry id */ Registry.prototype.get = function (id) { return this.entities[id]; }; /** * Returns raw entities from registry. */ Registry.prototype.snapshot = function () { return this.entities; }; /** * Override entities by external registry. * @internal * * @param otherRegistry external registry */ Registry.prototype.merge = function (otherRegistry) { var clone = new Registry({ id: this.id, overridable: this.overridable }); clone.fill(this.entities); if (!otherRegistry) return clone; var otherRegistryEntities = otherRegistry.snapshot(); for (var entityName in otherRegistryEntities) { if (!otherRegistryEntities.hasOwnProperty(entityName)) continue; clone.entities[entityName] = this.mergeEntities(clone.entities[entityName], otherRegistryEntities[entityName]); } return clone; }; /** * Returns extended or replaced entity * * @param base base implementation * @param overrides overridden implementation */ Registry.prototype.mergeEntities = function (base, overrides) { if (isOverload(overrides)) { if (!base) return overrides; if (isOverload(base)) { // If both entities are hocs, then create compose-hoc return withOverload(function (Base) { return overrides.overload(base.overload(Base)); }); } return overrides.overload(base); } return overrides; }; return Registry; }(); export { Registry };