
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
Stressless CSS for components using JS. Write Component Based CSS with functional mixins.
Stressless styles for components using js. Write CSS with functional mixins according to the component structure using components names.
npm install --save rockey
NOTE: that in most cases developers uses only getClassList and addParent methods. Other methods are mostly used in internal rockey infrastructure, for integrations with other libraries and for new features.
Very similar with css-modules.
import rule from 'rockey';
const css = rule`
Button {
color: black;
Icon {
margin: 5px;
}
}
`;
import rule from 'rockey';
const css = rule`
Button {
color: black;
Icon {
margin: 5px;
}
}
`;
const classList = css.getClassList();
const className = classList.Button;
Inserted CSS:
.Button-{{ hash }} {
color: black;
}
.Button-{{ hash }} .Icon-{{ hash }} {
margin: 5px;
}
Add parent rule. Child rule class names will be merged with parent. It is possible to add only one parent.
import rule from 'rockey';
const baseButtonCss = rule`
Button {
color: black;
background: white;
${props => props.small && `font-size: 12px;`}
}
`;
const primaryButtonCss = rule`
PrimaryButton {
color: blue;
}
`;
primaryButtonCss.addParent(baseButtonCss);
primaryButtonCss.getClassList({
small: true
});
const className = primaryButtonCss.PrimaryButton
// ['PrimaryButton-{{ hash }}', 'Button-{{ hash }}', 'AnonMixin1-{{ hash }}']
Inserted CSS:
.Button-{{ hash }} {
color: black;
background: white;
}
.PrimaryButton-{{ hash }} {
color: black;
background: white;
}
.AnonMixin1-{{ hash }}.Button-{{ hash }} {
font-size: 12px;
}
Wrap current rule with another selector.
import rule from 'rockey';
const css = rule`
Button {
color: black;
}
`;
css.wrapWith('Layer');
const classList = css.getClassList();
const className = classList.Layer
// ['Layer-{{ hash }}']
Inserted CSS:
.Layer-{{ hash }} .Button-{{ hash }} {
color: black;
}
NOTE: this method is mostly used in internal rockey infrastructure and for integrations with other libraries. Try not to use it in applications.
Api to add mixins. After this addMixins() rule should be wrapped with wrapWith()
import rule from 'rockey';
const css = rule`
color: black;
`;
css.addMixins([
props => props.small && `font-size: 12px;`
]);
css.wrapWith('Button');
const classList = css.getClassList({
small: true
});
const className = classList.Button;
// ['.Button-{{ hash }}', 'AnonMixin1-{{ hash }}']
NOTE: this method is mostly used in internal rockey infrastructure and for integrations with other libraries. Try not to use it in applications.
Transform current CSS tree and setup relations between defined components
For example: split rule into multiple rules and make each component to be child of previous component. This is how rockey-react looks feature works.
import rule from 'rockey';
const css = rule`
Base {
background: none;
${function isSmall(props) {
return props.small ? `font-size: 12px;` : null
}}
}
Sized {
font-size: 15px;
}
Colored {
color: red;
}
`;
const components = css.transform((tree, create) => {
const rules = {};
const components = Object.keys(tree.components);
for (let i = 0; i < components.length; i++) {
const displayName = components[i];
const rule = create(tree.components[displayName]);
if (i) {
const parentName = components[i - 1]
rule.addParent(rules[parentName]);
}
rules[displayName] = rule;
}
return rules;
});
components.Base.getClassList({
small: true
});
// ['.Base-{{ hash }}', '.Mixin-isSmall-{{ hash }}']
components.Sized.getClassList({
small: true
});
// ['.Sized-{{ hash }}', '.Base-{{ hash }}', '.Mixin-isSmall-{{ hash }}']
components.Colored.getClassList({
small: true
});
// ['.Colored-{{ hash }}', '.Sized-{{ hash }}', '.Base-{{ hash }}', '.Mixin-isSmall-{{ hash }}']
import when from 'rockey/when';
import { when } from 'rockey';
Helps to to keep syntax much better and cleaner when use mixins. Called each time with rule.getClassList().
import rule from 'rockey';
const css = rule`
Button {
color: black;
${rockey.when(props => props.primary)`
color: blue;
`}
Icon {
margin: 5px;
font-size: ${props => `${0.9 * props.scale}em`};
}
}
`;
const classList = css.getClassList({
primary: true
});
const className = classList.Button;
// ['.Button-{{ hash }}', '.AnonMixin1-{{ hash }}']
Inserted CSS:
.Button-{{ hash }} {
color: black;
}
.AnonMixin1-{{ hash }}.Button-{{ hash }} {
color: blue;
}
.Button-{{ hash }} .Icon-{{ hash }} {
font-size: 12px;
}
To provide more readable mixin class name - define mixin name at first argument.
import rule from 'rockey';
const css = rule`
Button {
color: black;
${rockey.when('isPrimary', props => props.primary)`
color: blue;
`}
Icon {
margin: 5px;
}
}
`;
const classList = css.getClassList({
primary: true
});
const className = classList.Button;
// ['.Button-{{ hash }}', '.isPrimary-{{ hash }}']
Inserted CSS:
.Button-{{ hash }} {
color: black;
}
.isPrimary-{{ hash }}.Button-{{ hash }} {
color: blue;
}
.Button-{{ hash }} .Icon-{{ hash }} {
font-size: 12px;
}
Access to props inside CSS rules:
import rule from 'rockey';
const css = rule`
Button {
color: black;
${rockey.when(props => props.color)(props => `
color: ${props.color};
`)}
Icon {
margin: 5px;
}
}
`;
import condition from 'rockey/condition';
import { condition } from 'rockey';
Same as when but it is called only when CSS string is parsing and does not takes props at arguments.
import rule from 'rockey';
const css = rule`
Button {
color: black;
${condition(isMobile())`
font-size: 10px;
`}
Icon {
margin: 5px;
}
}
`;
import { insert } from 'rockey';
import insert from 'rockey/insert';
Insert CSS rules to the DOM as is. Without any processing.
import rule from 'rockey';
rule.insert`
body {
overflow: hidden;
}
#hardcode {
color: red;
}
span.my {
color: green;
}
`;
This is a very new approach and library and not all features are implemented yet. Feel free to file issue or suggest feature to help me to make rockey better. Or ping me on twitter @tuchk4.
🎉
Upcoming plans:
FAQs
Stressless CSS for components using JS. Write Component Based CSS with functional mixins.
We found that rockey demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.