@wavevision/class-name
v1.0.1
Published
Create and format BEM class names for React components.
Downloads
27
Maintainers
Readme
Create and format BEM class names for React components. The formatter uses simplified BEM syntax.
Installation
Via Yarn
yarn add @wavevision/class-name
or npm
npm install --save @wavevision/class-name
Usage
Simple React component
import React, { useState, FunctionComponent } from 'react';
import className, { USE_VALUE } from '@wavevision/class-name';
interface ComponentProps {
align: string;
booleanProp: boolean;
nullableProp: string | null;
stringProp: string;
}
interface ComponentState {
visible: boolean;
}
// Define base class name with props and state behaving as modifiers
const componentClassName = className<ComponentProps, ComponentState>(
'component-class',
() => ({
// if booleanProp value is truthy, 'booleanProp' will be used as modifier
booleanProp: true,
// if stringProp value is truthy then the value will be used
stringProp: USE_VALUE,
// use callback for custom modifiers, string returned will be used
customModifier: ({ props }) => (props.nullableProp ? 'custom' : null),
// if a non-string truthy value is returned, key will be used
anotherModifier: ({ state }) => state.visible,
}),
);
// We can also have modifiers defined only if some condition is met
const anotherClassName = className<ComponentProps, ComponentState>(
'another-class',
({ props, state }) => {
if (props.nullableProp !== null) {
// the whole set of modifiers will be created only if nullableProp is not null
return { stringProps: USE_VALUE, customModifier: () => true };
}
if (state.visible) {
// this set will be created only if state.visible is true
return { customModifier: () => true };
}
},
);
const Component: FunctionComponent<ComponentProps> = props => {
const [visible] = useState<ComponentState['visible']>(false);
const className = componentClassName({ props, state: { visible } });
const nextClassName = anotherClassName({ props, state: { visible } });
return (
<div className={className.block('inline-modifier')}>
<div className={nextClassName.block()} />
<div
className={className.compose(
className.element('child'),
// extra class name with optional prefix (e.g. Bootstrap text utility)
className.extra(props.align, 'text'),
)}
/>
// modifiers can be nullable and will be used only if not null
<div className={className.element('element', props.nullableProp)} />
<div className={className.element('another', 'element-modifier')} />
</div>
);
};
will output following when rendered
<Component
align="right"
booleanProp={true}
nullableProp={null}
stringProp="something"
/>
<div
class="component-class component-class--boolean-prop component-class--something component-class--inline-modifier"
>
<div class="another-class"></div>
<div class="component-class__child text-right"></div>
<div class="component-class__element"></div>
<div
class="component-class__another component-class__another--element-modifier"
></div>
</div>