UNPKG

@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
# @vitus-labs/rocketstyle Multi-dimensional styling system for React. [![npm](https://img.shields.io/npm/v/@vitus-labs/rocketstyle)](https://www.npmjs.com/package/@vitus-labs/rocketstyle) [![license](https://img.shields.io/npm/l/@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 formreceives 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 dimensionmultiple 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