@vitus-labs/rocketstyle
Version:
Rocketstyle is ultra powerful and extensible styling system for building React components blazingly fast, easily and make them easily extensible and reusable.
325 lines (248 loc) • 8.1 kB
Markdown
# @vitus-labs/rocketstyle
Multi-dimensional styling system for React.
[](https://www.npmjs.com/package/@vitus-labs/rocketstyle)
[](https://github.com/vitus-labs/ui-system/blob/main/LICENSE)
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
```bash
npm install @vitus-labs/rocketstyle @vitus-labs/core
```
## Quick Start
```tsx
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 },
})
```
```tsx
// 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:
```tsx
.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:
```tsx
.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.
```tsx
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.
```tsx
Button.attrs({ tag: 'button', role: 'button' })
Button.attrs((props) => ({ 'aria-label': props.label }))
```
### .theme(values | callback)
Base theme values applied to every instance.
```tsx
// 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.
```tsx
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:
```tsx
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.
```tsx
Button.styles((css) => css`
cursor: pointer;
border: none;
transition: all 0.2s;
${({ $rocketstyle }) =>
makeItResponsive({ theme: $rocketstyle, styles, css })
}
`)
```
### .config(options)
Reconfigure the component.
```tsx
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`:
```tsx
Button.compose({ withTracking: trackingHoc })
Button.statics({ category: 'action' })
Button.meta.category // => 'action'
```
### isRocketComponent(value)
Runtime type guard.
```tsx
import { isRocketComponent } from '@vitus-labs/rocketstyle'
isRocketComponent(Button) // => true
```
## Custom Dimensions
Define your own dimensions by passing them to the factory:
```tsx
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.
```tsx
// 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:
```tsx
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