arto
Version:
Arto is a flexible and type-safe class name management library for building scalable UIs with variants, states, and conditional styling.
174 lines (136 loc) • 4.93 kB
Markdown
<h1 align="center">Arto</h1>
<div align="center">

[](https://www.npmjs.com/package/arto)


</div>
Arto is a **type-safe, flexible class name management library** designed for building scalable UIs with variants, states, and advanced conditional styling.
## Documentation
For full documentation, visit [arto.elgndy.com](https://arto.elgndy.com).
## Key Features
- 🎨 **Variants**: Cleanly define style options (e.g., size, color) without messy conditional logic.
- 🔄 **States**: Apply conditional classes for states like `disabled`, `hovered`, etc., with optional dependency logic.
- ⚡ **Rules & Logic**: Dynamically add or remove classes using logical operators (`AND`, `OR`, `XOR`, etc.) or custom callbacks.
- 🔧 **Fully Extensible**: Write or install plugins to extend functionality (e.g., theming, UI framework integration).
- 🛡️ **Type-Safe**: Built with TypeScript for robust validation and developer confidence.
- ✨ **Lightweight**: No external dependencies—integrates seamlessly with your chosen framework (React, Vue, Svelte, or plain JS).
- 🌐 **Framework Agnostic**: Compatible with any CSS strategy (e.g., Tailwind, PostCSS, CSS Modules).
## Installation
```bash
pnpm add arto
```
## Quick Example
Below is a very simplified example to illustrate how Arto might handle variants and states.
For more in-depth or real-world examples, see our [Documentation](https://arto.elgndy.com) and examples/ folder.
```ts
import { arto } from 'arto'
// 1. Create an arto instance with basic config
const myArto = arto({
// Always include these classes
className: 'btn',
// Define variants for styling
variants: {
size: {
small: 'btn-sm',
large: 'btn-lg',
},
},
// Define states for toggling
states: {
disabled: 'opacity-50 pointer-events-none',
},
})
// 2. Generate a final class string
const classString = myArto({
variants: { size: 'large' },
states: { disabled: true },
})
// => "btn btn-lg opacity-50 pointer-events-none"
```
## Advanced Example
Below is a more complex scenario showcasing:
- Nested state definitions with `dependsOn`
- Callback-based class names that leverage user-defined `context`
- Conditional logic through the rules `array`
```ts
import { arto } from 'arto'
// Define variant keys and possible values
type Variants = {
intent: 'info' | 'danger' | 'success'
size: 'sm' | 'md'
}
// Define possible states
type States = 'hovered' | 'disabled'
// Optional context data passed during class generation
type Context = {
username: string
}
const myArto = arto<Variants, States, Context>({
// Base classes
className: 'base',
// Variant definitions
variants: {
intent: {
info: 'intent-info',
danger: {
className: 'intent-danger',
states: {
hovered: {
className: 'intent-danger-hovered',
dependsOn: [{ not: ['disabled'] }], // apply only if 'disabled' is not active
},
},
},
// Callback-based class name
success: (ctx) => (ctx?.username === 'admin' ? 'intent-success-admin' : 'intent-success'),
},
size: {
sm: 'size-sm',
md: 'size-md',
},
},
// Global states
states: {
hovered: {
className: 'global-hovered',
dependsOn: [{ not: ['disabled'] }], // can't hover if disabled
},
disabled: 'global-disabled',
},
// Advanced rules
rules: [
{
when: {
variants: { intent: ['info', 'danger'] },
states: ['hovered'],
logic: 'AND',
},
add: 'rule-class',
},
],
})
// Usage examples:
// A) Info + small (no states)
const exampleA = myArto({
variants: { intent: 'info', size: 'sm' },
})
// => "base rule-class intent-info size-sm"
// B) Danger + hovered + disabled
const exampleB = myArto({
variants: { intent: 'danger', size: 'sm' },
states: { hovered: true, disabled: true },
})
// => "base rule-class intent-danger size-sm global-disabled"
// C) Success + hovered, with admin context
const exampleC = myArto({
variants: { intent: 'success', size: 'md' },
states: { hovered: true },
context: { username: 'admin' },
})
// => "base intent-success-admin size-md global-hovered"
```
## Contributing
We welcome contributions of all kinds, from bug reports to new features. Before submitting a pull request, please review our [Contributing Guide](https://arto.elgndy.com/contributing/contributing.html). It covers the recommended workflow, coding standards, and release process to help ensure a smooth collaboration.
## License
This project is released under the [MIT License](./LICENSE).