New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@bem-react/di

Package Overview
Dependencies
Maintainers
3
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bem-react/di - npm Package Compare versions

Comparing version 1.0.3 to 1.1.0

31

build/cjs/di.development.js

@@ -5,17 +5,28 @@ 'use strict';

var _assign = require('object-assign');
var React = require('react');
var __assign = function () {
__assign = _assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
return t;
};
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
return __assign.apply(this, arguments);
var __assign = function() {
__assign = Object.assign || function __assign(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);
};

@@ -22,0 +33,0 @@

@@ -1,1 +0,1 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var _assign=require("object-assign"),React=require("react"),__assign=function(){return(__assign=_assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var i in t=arguments[r])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)},registryContext=React.createContext({}),RegistryProvider=registryContext.Provider,RegistryConsumer=registryContext.Consumer;function withRegistry(){for(var i=[],e=0;e<arguments.length;e++)i[e]=arguments[e];return function(t){var e=function(e){return React.createElement(RegistryConsumer,null,function(r){var n={};return i.forEach(function(e){var t=r[e.id];n[e.id]=e.inverted?t||e:e||t}),React.createElement(RegistryProvider,{value:n},React.createElement(t,__assign({},e)))})};return e.displayName="RegistryResolver("+i.map(function(e){return e.id}).join(", ")+")",e}}var Registry=function(){function e(e){var t=e.id,r=e.inverted,n=void 0!==r&&r;this.components=new Map,this.id=t,this.inverted=n}return e.prototype.set=function(e,t){return this.components.set(e,t),this},e.prototype.get=function(e){return this.components.get(e)},e}();exports.RegistryConsumer=RegistryConsumer,exports.withRegistry=withRegistry,exports.Registry=Registry;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var React=require("react"),__assign=function(){return(__assign=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var i in t=arguments[r])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)},registryContext=React.createContext({}),RegistryProvider=registryContext.Provider,RegistryConsumer=registryContext.Consumer;function withRegistry(){for(var i=[],e=0;e<arguments.length;e++)i[e]=arguments[e];return function(t){var e=function(e){return React.createElement(RegistryConsumer,null,function(r){var n={};return i.forEach(function(e){var t=r[e.id];n[e.id]=e.inverted?t||e:e||t}),React.createElement(RegistryProvider,{value:n},React.createElement(t,__assign({},e)))})};return e.displayName="RegistryResolver("+i.map(function(e){return e.id}).join(", ")+")",e}}var Registry=function(){function e(e){var t=e.id,r=e.inverted,n=void 0!==r&&r;this.components=new Map,this.id=t,this.inverted=n}return e.prototype.set=function(e,t){return this.components.set(e,t),this},e.prototype.get=function(e){return this.components.get(e)},e}();exports.RegistryConsumer=RegistryConsumer,exports.withRegistry=withRegistry,exports.Registry=Registry;

@@ -6,2 +6,18 @@ # Change Log

# 1.1.0 (2018-12-06)
### Bug Fixes
* **di:** use map as class option for using in es5 ([24e9015](https://github.com/bem/bem-react/tree/master/packages/di/commit/24e9015))
### Features
* **v3:** init packages ([d652328](https://github.com/bem/bem-react/tree/master/packages/di/commit/d652328))
<a name="1.0.2"></a>

@@ -8,0 +24,0 @@ ## [1.0.2](https://github.com/bem/bem-react-core/compare/@bem-react/di@1.0.1...@bem-react/di@1.0.2) (2018-10-24)

import * as React from 'react';
export declare type RegistryContext = Record<string, Registry>;
export declare const RegistryConsumer: React.ComponentType<React.ConsumerProps<Record<string, Registry>>>;
export declare function withRegistry<P>(...registries: Registry[]): (Component: React.ComponentType<P>) => React.StatelessComponent<P>;
export declare const RegistryConsumer: React.ExoticComponent<React.ConsumerProps<Record<string, Registry>>>;
export declare function withRegistry<P>(...registries: Registry[]): (Component: React.ComponentType<P>) => React.FunctionComponent<P>;
export interface IRegistryOptions {

@@ -6,0 +6,0 @@ id: string;

{
"name": "@bem-react/di",
"version": "1.0.3",
"version": "1.1.0",
"description": "BEM React Dependency Injection",
"repository": {
"url": "git://github.com/bem/bem-react-core.git",
"type": "git"
},
"repository": "https://github.com/bem/bem-react/tree/master/packages/di",
"keywords": [
"bem",
"core"
"level",
"dependency",
"di",
"dependency injection",
"react"
],

@@ -13,0 +14,0 @@ "main": "index.js",

@@ -1,134 +0,123 @@

# DI
# Dependency Injection (DI)
DI (dependency injection) is very simple way to use any versions of components in any place of your App.
**Dependency Injection (DI)** allows you to split React components into separate versions and comfortably switch them in the project whenever needed, e.g., to make a specific bundle.
Let's see an example.
DI package helps to solve similar tasks with minimum effort:
- decouple *desktop* and *mobile* versions of a component
- implement an *experimental* version of a component alongside the common one
## Problem
## Install
```
npm i @bem-react/di -S
```
You already wrote React-components for your BEM App:
```tsx
// components/Button/Button.tsx
## Quick start
import * as React from 'react';
import { cn } from '@bem-react/classname';
**Note!** This example uses [ClassName package](https://github.com/bem/bem-react/tree/master/packages/classname).
const cnButton = cn('Button');
E.g., for a structure like this:
```
Components/
Header/
Header@desktop.tsx
Header@mobile.tsx
Footer/
Footer@desktop.tsx
Footer@mobile.tsx
App.tsx
```
export interface IButtonProps {
text: string;
}
First, create two files that define two versions of the App and use different sets of components: `App@desktop.tsx` and `App@mobile.tsx`. Put them near `App.tsx`.
export interface IButtonState {
pointed: boolean;
}
export class Button extends React.Component<IButtonProps, IButtonState> {
constructor() {
this.state = { pointed: false };
}
private onPointerEnter() {
this.setState({ pointed: true });
}
private onPointerLeave() {
this.setState({ pointed: false });
}
protected abstract attrs: () => React.DOMAttributes;
render() {
return (
<div className={cnButton(this.state)} {...this.attrs()}>
{this.props.text}
</div>
);
}
}
// components/App/App.tsx
import * as React from 'react';
import { Button } from '../Button/Button';
export const App: React.SFC = () => <Button text="Hello there!" />;
In each App version (`App@desktop.tsx` and `App@mobile.tsx`) we should define which components should be used.
Three steps to do this:
1. Create a registry with a particular id:
```javascript
const registry = new Registry({ id: cnApp() });
```
2. Register all the needed components versions under a descriptive key (keys, describing similar components, should be the same across all the versions):
```javascript
registry.set(cnHeader(), Header);
registry.set(cnFooter(), Footer);
```
3. Export the App version with its registry of components:
```javascript
export const AppNewVersion = withRegistry(registry)(AppCommon);
```
At some point you realized that "Button" should behave differently on desktop and mobile platforms.
The files should look like this:
Two questions:
**1.** In `App@desktop.tsx`
```javascript
import { cn } from '@bem-react/classname';
import { Registry, withRegistry } from '@bem-react/di';
import { App as AppCommon } from './App';
- **Q1.** How to describe two versions of "Button"?
- **Q2.** How to do import specific version of "Button" with minimum effort?
import { Footer } from './Components/Footer/Footer@desktop';
import { Header } from './Components/Header/Header@desktop';
## Solution
const cnApp = cn('App');
const cnHeader = cn('Header');
const cnFooter = cn('Footer');
**A1.** Describing two versions of a component:
const registry = new Registry({ id: cnApp() });
```tsx
// components/Button/Button@desktop.tsx - desktop version
registry.set(cnHeader(), Header);
registry.set(cnFooter(), Footer);
import * as React from 'react';
import { Button as ButtonCommon } from './Button';
export class Button extends ButtonCommon {
protected attrs() {
return {
onMouseEnter: this.onPointerEnter,
onMouseLeave: this.onPointerLeave,
};
}
}
// components/Button/Button@mobile.tsx - mobile version
import * as React from 'react';
import { Button as ButtonCommon } from './Button';
export class Button extends ButtonCommon {
protected attrs() {
return {
onTouchMove: this.onPointerEnter,
onTouchEnd: this.onPointerLeave,
};
}
}
export const AppDesktop = withRegistry(registry)(AppCommon);
```
**A2.** Importing components with "di":
```tsx
// components/App/App@desktop.tsx
**2.** In `App@mobile.tsx`
```javascript
import { cn } from '@bem-react/classname';
import { Registry, withRegistry } from '@bem-react/di';
import { cn } from '@bem-react/classname';
import { App as AppCommon } from './App';
import { Button } from '../Button/Button@desktop';
import { Footer } from './Components/Footer/Footer@mobile';
import { Header } from './Components/Header/Header@mobile';
const cnApp = cn('App');
const cnButton = cn('Button');
const cnHeader = cn('Header');
const cnFooter = cn('Footer');
// registry with desktop versions of components
const registry = new Registry({ id: cnApp() });
registry.set(cnButton(), Button);
registry.set(cnHeader(), Header);
registry.set(cnFooter(), Footer);
export const App = withRegistry(registry)(AppCommon);
export const AppMobile = withRegistry(registry)(AppCommon);
```
// components/App/App@mobile.tsx
//
// ...very similar...
//
Time to use these versions in your app dynamically!
If in `App.tsx` your dependencies were static before
```javascript
import { cn } from '@bem-react/classname';
import { Header } from './Components/Header/Header';
import { Footer } from './Components/Footer/Footer';
// components/App/App.tsx - with small changes
const cnPage = cn('Page');
import * as React from 'react';
export const App: React.SFC = () => (
<div className={ cnPage() }>
<Header />
<Content />
<Footer />
</div>
);
```
Now the dependencies can be injected based on the currently used registry
```javascript
import { cn } from '@bem-react/classname';
import { RegistryConsumer } from '@bem-react/di';
import { IButtonProps } from '../Button/Button';
// No Header or Footer imports
const cnApp = cn('App');
const cnButton = cn('Button');
const cnPage = cn('Page');
const cnHeader = cn('Header');
const cnFooter = cn('Footer');

@@ -138,12 +127,27 @@ export const App: React.SFC = () => (

{registries => {
// reading App registry
// Get registry with components
const registry = registries[cnApp()];
// Get the needed version of the component based on registry
const Header = registry.get(cnHeader());
const Footer = registry.get(cnFooter());
// taking desktop or mobile version
const Button = registry.get<IButtonProps>(cnButton());
return <Button text="Hello there!" />;
return(
<div className={ cnPage() }>
<Header />
<Content />
<Footer />
</div>
);
}}
</RegistryConsumer>
);
export default App;
```
So you could use different versions of your app e.g. for conditional rendering on your server side or to create separate bundles
```javascript
import { AppDesktop } from './path-to/App@desktop';
import { AppMobile } from './path-to/App@mobile';
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc