PitchHut logo
Log in / Sign up
Arto
by loose_harlequin_kylie
A type-safe library for flexible class name management in scalable UIs.
Pitch

Arto provides a robust solution for class name management, allowing developers to create flexible and type-safe UI components. With features like cleanly defined variants, conditional states, and logical rules, it integrates seamlessly with any framework and CSS strategy, enhancing scalability without external dependencies.

Description

Arto is a type-safe and flexible class name management library that facilitates the construction of scalable user interfaces. It offers a sophisticated system for working with variants, states, and advanced conditional styling, making it an essential tool for developers looking to enhance their UI design capabilities.

Key Features

  • Variants: Easily define style options such as size and color without resorting to complicated conditional logic.
  • States: Conditional classes can be applied for various states like disabled and hovered, with optional dependency logic.
  • Rules & Logic: Allow for dynamic addition or removal of classes using logical operators (AND, OR, XOR, etc.) or custom callbacks.
  • Fully Extensible: Supports the integration of plugins, enabling additional functionality like theming and compatibility with various UI frameworks.
  • Type-Safe: Developed with TypeScript, ensuring robust validation for greater developer confidence and reliability.
  • Lightweight: Works without external dependencies, integrating smoothly with any selected framework, including React, Vue, and Svelte.
  • Framework Agnostic: Compatible with any CSS strategy, such as Tailwind, PostCSS, or CSS Modules.

Quick Example

Here is a simplified example demonstrating how to effectively utilize Arto:

import { arto } from 'arto'

// Create an instance of arto with basic configuration
const myArto = arto({
  className: 'btn',
  variants: {
    size: {
      small: 'btn-sm',
      large: 'btn-lg',
    },
  },
  states: {
    disabled: 'opacity-50 pointer-events-none',
  },
})

// Generate the final class string
const classString = myArto({
  variants: { size: 'large' },
  states: { disabled: true },
})

// => "btn btn-lg opacity-50 pointer-events-none"

Advanced Example

A more complex example is as follows, showcasing advanced features such as nested state definitions and conditional logic:

import { arto } from 'arto'

type Variants = {
  intent: 'info' | 'danger' | 'success'
  size: 'sm' | 'md'
}
type States = 'hovered' | 'disabled'
type Context = {
  username: string
}

const myArto = arto<Variants, States, Context>({
  className: 'base',
  variants: {
    intent: {
      info: 'intent-info',
      danger: {
        className: 'intent-danger',
        states: {
          hovered: {
            className: 'intent-danger-hovered',
            dependsOn: [{ not: ['disabled'] }],
          },
        },
      },
      success: (ctx) => (ctx?.username === 'admin' ? 'intent-success-admin' : 'intent-success'),
    },
    size: {
      sm: 'size-sm',
      md: 'size-md',
    },
  },
  states: {
    hovered: {
      className: 'global-hovered',
      dependsOn: [{ not: ['disabled'] }],
    },
    disabled: 'global-disabled',
  },
  rules: [
    {
      when: {
        variants: { intent: ['info', 'danger'] },
        states: ['hovered'],
        logic: 'AND',
      },
      add: 'rule-class',
    },
  ],
})

// Usage examples:
const exampleA = myArto({
  variants: { intent: 'info', size: 'sm' },
})
// => "base rule-class intent-info size-sm"

const exampleB = myArto({
  variants: { intent: 'danger', size: 'sm' },
  states: { hovered: true, disabled: true },
})
// => "base rule-class intent-danger size-sm global-disabled"

const exampleC = myArto({
  variants: { intent: 'success', size: 'md' },
  states: { hovered: true },
  context: { username: 'admin' },
})
// => "base intent-success-admin size-md global-hovered"

Documentation

For comprehensive documentation and further details, please visit arto.elgndy.com.

Contributions to the project are welcome and encouraged. For guidelines on contributing, refer to the Contributing Guide.

0 comments

No comments yet.

Sign in to be the first to comment.