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

react-decorators

Package Overview
Dependencies
Maintainers
2
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-decorators - npm Package Compare versions

Comparing version 1.0.2 to 1.0.4

class-names.js

76

css-modules.js

@@ -1,69 +0,19 @@

var classNames = require('classnames/bind');
var utils = require('./utils');
var React = require('react');
var propertiesTransformer = require('./lib/properties-transformer');
var _classNames = require('classnames/bind');
var classNames = require('./class-names');
/**
*
* @param styles
* @returns {function(*=): *}
*/
module.exports = function cssModules(styles) {
return function(Component) {
if (utils.isStatelessComponent(Component)) {
return function(props) {
return transformElement(Component(props), classNames.bind(styles));
};
}
function StyledComponent() {
Component.prototype.constructor.apply(this, arguments);
}
utils.classInheritance(StyledComponent, Component);
StyledComponent.prototype.render = function() {
return transformElement(
Component.prototype.render.apply(this, arguments),
classNames.bind(styles)
);
};
return StyledComponent;
};
};
function transformElement(el, cx) {
if (el) {
if (el.props) {
var props = Object.assign({}, el.props);
Object.keys(props).forEach(function(propName) {
if (React.isValidElement(props[propName])) {
props[propName] = transformElement(props[propName], cx);
}
});
var cx = _classNames.bind(styles);
return propertiesTransformer(Component, function(props) {
if (props.className) {
props.className = cx(splitStrings(props.className));
props.className = cx(classNames.splitStrings(props.className));
}
el = React.cloneElement(el, props, recursiveTransform(props.children, cx));
}
else {
// no props currently means that this is in fact a portal, not an element
// therefore we only transform the children, we cannot clone it
el.children = recursiveTransform(el.children, cx);
}
}
return el;
}
function recursiveTransform(el, cx) {
if (React.isValidElement(el)) {
return transformElement(el, cx);
}
if (Array.isArray(el)) {
return React.Children.map(el, function(child) {
return recursiveTransform(child, cx);
});
}
return el;
}
function splitStrings(className) {
if (Array.isArray(className)) {
return className.map(splitStrings);
}
if (typeof className === 'string') {
return className.split(/\s+/g);
}
return className;
}
};
};
var lib = module.exports;
lib.consumeContext = require('./consume-context');
lib.cssModules = require('./css-modules');
lib.injectContext = require('./inject-context');
lib.classNames = require('./class-names');
lib.cssModules = require('./css-modules');
{
"name": "react-decorators",
"version": "1.0.2",
"version": "1.0.4",
"description": "A collection of react decorators to enhance components capabilities",

@@ -8,3 +8,4 @@ "main": "./index.js",

"preversion": "npm test",
"test": "npx mocha --require babel-register tests/"
"prepublish": "npm test",
"test": "npx mocha --require ./tests/bootstrap tests/"
},

@@ -24,3 +25,3 @@ "repository": {

"author": "Ido Moshe",
"license": "ISC",
"license": "MIT",
"bugs": {

@@ -38,2 +39,3 @@ "url": "https://github.com/iMoses/react-decorators/issues"

"babel-cli": "^6.26.0",
"babel-plugin-rewire": "^1.1.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",

@@ -47,4 +49,5 @@ "babel-preset-env": "^1.6.1",

"enzyme-adapter-react-16": "^1.1.1",
"jsdom": "^11.9.0",
"mocha": "^5.1.0"
}
}

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

# React-decorators
# React-decorators
_A collection of react decorators to enhance components capabilities._
Feel free to open a PR with your own decorators. For large
new features, please open an issue first.
## Installation
The package is currently available only on [npm](https://www.npmjs.com/).
```shell
npm install --save react-decorators
```
[![npm/react-decorators](https://nodei.co/npm/react-decorators.png?compact=true)](https://www.npmjs.org/package/react-decorators)
## Usage
## Decorators
- [classNames](#classnames)
- [cssModules](#cssmodules)
- [injectContext](#injectcontext)
### classNames
**What is does**
Injects the [classnames](https://github.com/JedWatson/classnames) package directly into React's `className` property.
> A simple JavaScript utility for conditionally joining classNames together.
> <br/>...<br/>
> The `classNames` function takes any number of arguments which can be a string or object.
> <br/>...<br/>
> If the value associated with a given key is falsy, that key won't be included in the output.
```javascript
@classNames
class MyComponent extends React.Component {
render() {
return (
<div className="classnames-examples">
<span className={['foo', 'bar']} /> {/* class="foo bar" */}
<span className={{selected: false, visible: true}} /> {/* class="visible" */}
<span className={[null, {active: true}, false, [{nested: true}]]} /> {/* class="active nested" */}
<span className={{hasClass: false}} /> {/* class="" */}
</div>
);
}
}
```
### cssModules
**What is does**
An extension of the [`classNames`](#classnames) decorator, it binds the
[classnames](https://github.com/JedWatson/classnames) package to React's `className` property using the
[alternate `bind` version](https://github.com/JedWatson/classnames#alternate-bind-version-for-css-modules)
for [css-modules](https://github.com/css-modules/css-modules).
```
import styles from './styles.css';
@cssModules(styles)
class MyComponent extends React.Component {
render() {
return (
<div className="my-class">
// Content goes here
</div>
);
}
}
```
Although it mixing between ES2015+ `imports` and CommonJS `require`,
I find this syntax to be very readable.
```js
@cssModules(require('./my-component.scss'))
class MyComponent extends React.Component { ... }
```
### injectContext
**What is does**
This decorator receives a map of property names to context consumers,
and injects these the consumers values as properties to the base component.
`injectContext({propName: Consumer[, ...]})`
```js
@injectContext({
theme: ThemeConsumer,
})
class MyComponent extends React.Component {
render() {
return (
<div className={this.props.theme.container}>
// Content goes here
</div>
);
}
}
```

@@ -0,9 +1,8 @@

import cssModules from '../css-modules';
import { shallow, mount } from 'enzyme';
import ReactDOM from 'react-dom';
import { expect } from 'chai';
import { JSDOM } from 'jsdom';
import React from 'react';
import { expect } from 'chai';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import cssModules from '../css-modules';
Enzyme.configure({adapter: new Adapter});
describe('@cssModules', () => {

@@ -18,81 +17,57 @@

describe('React.Component', () => {
const PropsComponent = props => (
<div className="spanClass">
{props.child}
</div>
);
@cssModules(styles)
class TestComponent extends React.Component {
@cssModules(styles)
class TestComponent extends React.Component {
render() {
const { divClass, spanClass, codeClass } = this.props;
const PropsComponent = props => props.child;
return (
<div className={divClass}>
<span className={spanClass} />
<PropsComponent child={<code className={codeClass} />} />
</div>
);
}
render() {
const { divClass, spanClass, codeClass, children } = this.props;
// const PropsComponent = props => props.child;
return (
<div className={divClass}>
<span className={spanClass} />
<PropsComponent child={<code className={codeClass} />} />
<code>{children}</code>
</div>
);
}
const el = shallow(
<TestComponent
divClass="div-class"
codeClass="code-class"
spanClass={[{spanClass: true, ignoreClass: false}, 'extra-class']}
/>
);
}
it('transform a string className', () => {
expect(el.find('div').props().className).to.equal('div-class-name');
});
const el = shallow(
<TestComponent
divClass="div-class"
codeClass="code-class"
spanClass={[{spanClass: true, ignoreClass: false}, 'extra-class']}>
Child
</TestComponent>
);
it('transform a nested object/array className', () => {
expect(el.find('span').props().className).to.include('span-class-name');
expect(el.find('span').props().className).to.include('extra-class');
expect(el.find('span').props().className).to.not.include('spanClass');
expect(el.find('span').props().className).to.not.include('ignoreClass');
expect(el.find('span').props().className).to.not.include('should-not-appear');
});
it('validate `children` is not being lost', () => {
expect(el.find('code').text()).to.equal('Child');
});
it('transform a property element className', () => {
expect(el
.find('PropsComponent').shallow()
.find('code').props().className
).to.include('code-class-name');
});
it('transforms a string className', () => {
expect(el.find('div').props().className).to.equal('div-class-name');
});
it('transform className inside a portal', () => {});
it('transform className inside fragments', () => {});
it('transforms a nested object/array className', () => {
expect(el.find('span').props().className).to.include('span-class-name');
expect(el.find('span').props().className).to.include('extra-class');
expect(el.find('span').props().className).to.not.include('spanClass');
expect(el.find('span').props().className).to.not.include('ignoreClass');
expect(el.find('span').props().className).to.not.include('should-not-appear');
});
describe('Stateless Component', () => {
const TestComponent = cssModules(styles)(props =>
<div className={props.divClass}>
<span className={props.spanClass} />
</div>
);
const el = shallow(
<TestComponent
divClass="div-class"
spanClass={[{spanClass: true, ignoreClass: false}, 'extra-class']} />
);
it('transform a string className', () => {
expect(el.find('div').props().className).to.equal('div-class-name');
});
it('transform a nested object/array className', () => {
expect(el.find('span').props().className).to.include('span-class-name');
expect(el.find('span').props().className).to.include('extra-class');
expect(el.find('span').props().className).to.not.include('spanClass');
expect(el.find('span').props().className).to.not.include('ignoreClass');
expect(el.find('span').props().className).to.not.include('should-not-appear');
});
it('transforms a property element className', () => {
expect(el
.find('PropsComponent').shallow()
.find('code').props().className
).to.include('code-class-name');
});
});

Sorry, the diff of this file is not supported yet

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