@vitus-labs/rocketstyle
v2.6.0
Published
Rocketstyle is ultra powerful and extensible styling system for building React components blazingly fast, easily and make them easily extensible and reusable.
Maintainers
Readme
@vitus-labs/rocketstyle
Multi-dimensional styling system for React.
Organize component styles by dimensions — states, sizes, variants — instead of flat props. Chain theme values, attach CSS via the active connector, and get full TypeScript inference. Built-in pseudo-state handling, light/dark mode, and provider/consumer patterns for parent-child state propagation.
Features
- Dimension-based theming — define style variations as named dimensions (states, sizes, variants)
- Immutable chaining —
.attrs(),.theme(),.states(),.sizes(),.styles()and more - Boolean shorthand —
<Button primary lg>instead of<Button state="primary" size="lg"> - Pseudo-state detection — hover, focus, pressed, active tracked via context
- Light/dark mode — theme callbacks receive a mode parameter
- Provider/Consumer — propagate parent state to children through context
- WeakMap caching — computed themes cached per component instance
- TypeScript inference — dimension values and prop types inferred through the chain
Installation
npm install @vitus-labs/rocketstyle @vitus-labs/coreQuick Start
import rocketstyle from '@vitus-labs/rocketstyle'
import { Element } from '@vitus-labs/elements'
const Button = rocketstyle()({
name: 'Button',
component: Element,
})
.attrs({ tag: 'button' })
.theme({
fontSize: 16,
paddingX: 16,
paddingY: 8,
borderRadius: 4,
color: '#fff',
backgroundColor: '#0d6efd',
hover: {
backgroundColor: '#0b5ed7',
},
})
.states({
primary: {
backgroundColor: '#0d6efd',
hover: { backgroundColor: '#0b5ed7' },
},
danger: {
backgroundColor: '#dc3545',
hover: { backgroundColor: '#bb2d3b' },
},
success: {
backgroundColor: '#198754',
hover: { backgroundColor: '#157347' },
},
})
.sizes({
sm: { fontSize: 14, paddingX: 12, paddingY: 6 },
md: { fontSize: 16, paddingX: 16, paddingY: 8 },
lg: { fontSize: 18, paddingX: 20, paddingY: 10 },
})// Named props
<Button state="danger" size="lg" label="Delete" />
// Boolean shorthand (when useBooleans is enabled)
<Button danger lg label="Delete" />Core Concepts
Dimensions
A dimension is a named axis of style variation. The factory ships with four defaults:
| Dimension | Prop name | Multi | Example |
| --------- | --------- | ----- | ------- |
| states | state | no | primary, danger, success |
| sizes | size | no | sm, md, lg |
| variants | variant | no | outlined, filled |
| multiple | — | yes | rounded, shadow |
Each dimension creates a chain method (.states(), .sizes(), etc.) and a corresponding prop on the component.
Multi dimensions allow multiple values at once: <Button rounded shadow>.
Theme Object
The .theme() method defines base CSS property values. Values are processed by @vitus-labs/unistyle — numbers convert to rem, shorthand properties expand automatically.
Pseudo-state keys nest directly in the theme object:
.theme({
color: '#333',
fontSize: 16,
hover: { color: '#000' },
focus: { outline: '2px solid blue' },
active: { transform: 'scale(0.98)' },
})Styles Function
The .styles() method defines the CSS template that receives the computed theme:
.styles((css) => css`
${({ $rocketstyle, $rocketstate }) => {
// $rocketstyle — computed theme values (base + active dimension values merged)
// $rocketstate — { hover, focus, pressed, active, disabled, pseudo }
return css`...`
}}
`)API
rocketstyle(options?)
Factory initializer. Returns a function that accepts component configuration.
const factory = rocketstyle({
dimensions: { /* custom dimensions */ },
useBooleans: true,
})
const Component = factory({
name: 'ComponentName',
component: BaseComponent,
}).attrs(props | callback, options?)
Same API as @vitus-labs/attrs. Define default props with optional priority and filter.
Button.attrs({ tag: 'button', role: 'button' })
Button.attrs((props) => ({ 'aria-label': props.label })).theme(values | callback)
Base theme values applied to every instance.
// Object form
Button.theme({
fontSize: 16,
color: '#fff',
hover: { opacity: 0.9 },
})
// Callback form — receives the theme context and mode
Button.theme((theme, mode, css) => ({
fontSize: 16,
color: mode === 'dark' ? '#fff' : '#333',
})).states() / .sizes() / .variants() / .multiple()
Define values for each dimension. Each key becomes a selectable option.
Button.states({
primary: { backgroundColor: '#0d6efd' },
danger: { backgroundColor: '#dc3545' },
})
Button.sizes({
sm: { fontSize: 14, paddingX: 8 },
lg: { fontSize: 18, paddingX: 20 },
})
// Multi dimension — multiple can be active at once
Button.multiple({
rounded: { borderRadius: 999 },
shadow: { boxShadow: '0 2px 8px rgba(0,0,0,0.15)' },
})Dimension methods also accept callbacks:
Button.states((theme, mode, css) => ({
primary: { backgroundColor: theme.colors?.primary ?? '#0d6efd' },
})).styles(callback)
Define the CSS template using the active connector's css tagged template.
Button.styles((css) => css`
cursor: pointer;
border: none;
transition: all 0.2s;
${({ $rocketstyle }) =>
makeItResponsive({ theme: $rocketstyle, styles, css })
}
`).config(options)
Reconfigure the component.
Button.config({
name: 'PrimaryButton', // change displayName
component: NewBase, // swap base component
provider: true, // make this component a context provider
consumer: (ctx) => ..., // consume parent component context
inversed: true, // invert theme mode
DEBUG: true, // enable debug logging
}).compose(hocs) / .statics(metadata)
Same API as @vitus-labs/attrs:
Button.compose({ withTracking: trackingHoc })
Button.statics({ category: 'action' })
Button.meta.category // => 'action'isRocketComponent(value)
Runtime type guard.
import { isRocketComponent } from '@vitus-labs/rocketstyle'
isRocketComponent(Button) // => trueCustom Dimensions
Define your own dimensions by passing them to the factory:
const rocketButton = rocketstyle({
dimensions: {
intent: 'intent', // prop: intent="primary"
size: 'size', // prop: size="lg"
appearance: {
propName: 'appearance',
multi: true, // allows multiple: <Button rounded outlined>
},
},
})This creates .intent(), .size(), and .appearance() chain methods.
Provider / Consumer
Propagate parent component state to children through context.
// Parent provides its state
const ButtonGroup = Button.config({ provider: true })
// Child consumes parent state
const ButtonIcon = rocketstyle()({
name: 'ButtonIcon',
component: Element,
})
.config({
consumer: (ctx) => ctx<typeof ButtonGroup>(({ pseudo }) => ({
state: pseudo.hover ? 'active' : 'default',
})),
})
.states({
default: { color: '#666' },
active: { color: '#fff' },
})
// Icon reacts to parent's hover state
<ButtonGroup state="primary">
<ButtonIcon />
<span>Label</span>
</ButtonGroup>Light / Dark Mode
Theme callbacks receive a mode parameter:
Button.theme((theme, mode) => ({
color: mode === 'dark' ? '#fff' : '#1a1a1a',
backgroundColor: mode === 'dark' ? '#333' : '#fff',
}))Use inversed: true in .config() to flip the mode for a component subtree.
Peer Dependencies
| Package | Version | | ------- | ------- | | react | >= 19 | | @vitus-labs/core | * |
License
MIT
