react-suitcssify
v3.3.0
Published
A React component utility to generate CSS class names that conform to SUIT CSS naming conventions.
Downloads
598
Readme
react-suitcssify
A React component utility to generate CSS class names that conform to SUIT CSS naming conventions.
This utility can be used as a higher-order component, decorator, mixin, or utility function. This means that you can use it with React components defined using createClass, ES2015 classes, or stateless-functional components.
Provides a general purpose getClassName(options)
method that accepts a variety of options for generating SUIT CSS conformant class names.
getClassName({
baseComponentName: string,
className: string,
componentName: string,
descendantName: string,
modifiers: string,
namespace: string,
states: string,
utilities: string
})
When using the decorator or mixin approach, the following defaults are provided.
- className -
Component.props.className
Note thatComponent.propTypes.className
is also added for convenience. - componentName -
Component.displayName || Component.name
- namespace -
Component.namespace
- utilities -
Component.props.utilities
Note thatComponent.propTypes.utilities
is also added for convenience.
When using the higher-order approach, the following defaults are provided.
- className -
Component.props.className
- componentName -
Component.displayName || Component.name
- utilities -
Component.props.utilities
Installation
npm install react-suitcssify
Usage
ES2015 class with a decorator
import React from 'react';
import ReactDOM from 'react-dom';
import SuitCssify from 'react-suitcssify';
@SuitCssify.decorator
class MyComponent extends React.Component {
render() {
return <div className={ this.getClassName() }></div>
}
}
ReactDOM.render(<MyComponent/>, document.body);
- NOTE: Your codebase must support ES7 decorators to use this syntax. Alternatively, simply use the decorator as a wrapper function to achieve the same effect.
As a higher-order component
This decorator approach does not work with stateless functional React components. This approach will pass in the getClassName
function as a prop to your component.
import React from 'react';
import ReactDOM from 'react-dom';
import SuitCssify from 'react-suitcssify';
const MyComponent = ({ getClassName }) => <div className={ getClassName() }></div>;
const WrappedComponent = SuitCssify.higherOrder('optional_namespace')(MyComponent);
ReactDOM.render(<WrappedComponent/>, document.body);
Here's an example with an ES2015 class React component.
import React from 'react';
import ReactDOM from 'react-dom';
import SuitCssify from 'react-suitcssify';
class MyComponent extends React.Component {
static propTypes = {
getClassName: React.PropTypes.func.isRequired
};
render() {
return <div className={ this.props.getClassName() }></div>
}
}
const WrappedComponent = SuitCssify.higherOrder('optional_namespace')(MyComponent);
ReactDOM.render(<WrappedComponent/>, document.body);
As a mixin
import React from 'react';
import ReactDOM from 'react-dom';
import SuitCssify from 'react-suitcssify';
const MyComponent = React.createClass({
mixins: [SuitCssify.mixin],
render: function() {
return <div className={ this.getClassName() }></div>
}
});
ReactDOM.render(<MyComponent/>, document.body);
Calling getClassName directly
import React from 'react';
import ReactDOM from 'react-dom';
import SuitCssify from 'react-suitcssify';
const getClassName = SuitCssify.getClassName;
class MyComponent extends React.Component {
render() {
return <div className={ getClassName({ componentName: 'MyComponent', namespace: 'my' }) }></div>
}
}
ReactDOM.render(<MyComponent/>, document.body);
A more performant implementation of a component using the getClassName
function directly is to instead call getBaseComponentName which pre-calculates the baseComponentName one time given the componentName and namespace instead of calculating it on every call. While being slightly more verbose than the other options, it will provide better performance than all the other approaches. Here's what that looks like:
const displayName = 'MyComponent';
const namespace = 'my';
const baseComponentName = SuitCssify.getBaseComponentName(displayName, namespace);
const getClassName = SuitCssify.getClassName;
class MyComponent extends React.Component {
render() {
return <div className={ getClassName({ baseComponentName }) }></div>
}
}
ReactDOM.render(<MyComponent/>, document.body);
Each of the above render as:
<div class="MyComponent"></div>
Examples
Assuming we have the following component
<Component />
We should expect the following output.
getClassName() -----> 'Component'
getClassName({ componentName: 'AwesomeComponent' }) -----> 'AwesomeComponent'
getClassName({ namespace: 'my' }) -----> 'my-Component'
getClassName({ modifiers: 'foo bar' }) -----> 'Component Component--foo Component--bar'
getClassName({ states: 'active' }) -----> 'Component is-active'
getClassName({ utilities: 'floatRight' }) -----> 'Component u-floatRight'
getClassName({ className: 'arbitrary' }) -----> 'Component arbitrary'
getClassName({ descendantName: 'title' }) -----> 'Component Component-title'
getClassName({
className: 'arbitrary',
componentName: 'AwesomeComponent',
modifiers: 'foo bar',
namespace: 'my',
states: 'active',
utilities: 'floatRight'
}) -----> 'my-AwesomeComponent my-AwesomeComponent--foo my-AwesomeComponent--bar is-active u-floatRight arbitrary'
getClassName({
componentName: 'AwesomeComponent',
namespace: 'my',
modifiers: 'foo bar',
states: 'active',
utilities: 'floatRight',
className: 'arbitrary',
descendantName: 'child'
}) -----> 'my-AwesomeComponent-child my-AwesomeComponent-child--foo my-AwesomeComponent-child--bar is-active u-floatRight arbitrary'
const baseComponentName = getBaseComponentName('Component', 'my');
getClassName({
baseComponentName
}) -----> 'my-Component'
For more examples, browse the demo files or just run the demo.
Demo
npm run demo
Build
npm run build
Tests
npm test
Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code.
Release History
- 3.2.0 - Add getBaseComponentName to API. Alias
utility
asgetClassName
-- utility will be removed in a future release as it would be a breaking change. - 3.1.0 - Add higher-order component option. Update React version and add to peerDependencies. Other minor tweaks.
- 3.0.2 - Update decorator to not use inheritance. Update dev dependencies, including react 0.14.
- 3.0.1 - Use destructuring assignment instead of Object.assign. Utilize internal format method to de-dupe similar code. Adjust imports.
- 3.0.0 - Descendant elements no longer automatically inherit parent className.
- 2.0.2 - Add extra this.props check when using as utility.
- 2.0.1 - Remove React as peer dependency.
- 2.0.0 - Extend capabilities for use as decorator, mixin, or utility method. Project renamed to react-suitcssify. To upgrade, simply change the import/require to use the desired type (decorator, mixin, or utility) as shown in the usage section above.
- 1.0.1 - Update dependencies. Fix test mock. Update readme.
- 1.0.0 - Camelize and capitalize componentName
- 0.0.5 - Use Object.assign polyfill from react/lib. Update .npmignore and readme.
- 0.0.4 - Initial release