๐Ÿงช Atomify

Small. Reactive. Simple.

Atomify is an idiomatic Dart library for building web applications with a laser focus on simplicity and reactivity. Atomify breaks down UI development into atomic, composable elements that are both lightweight and powerful.

Documentation

Atomify Documentation

โœจ Why Atomify?

  • ๐Ÿชถ Minimal Footprint: Built to be lightweight without sacrificing functionality
  • โšก Reactive by Design: State changes automatically trigger UI updates
  • ๐Ÿงฉ Atomic Components: Everything is a composable Box - from simple text to complex layouts
  • ๐Ÿ“ฆ Zero Dependencies: Only depends on web and cssify packages
  • ๐ŸŽฏ Idiomatic Dart: Leverages Dart's strengths for clean, readable code

๐Ÿš€ Quick Start

Installation

Add Atomify to your pubspec.yaml:

dependencies:
  atomify: ^0.1.0

Hello World

import 'package:atomify/atomify.dart';

void main() {
  App(
    children: [
      Container(
        children: [
          Text('Hello, Atomify! ๐Ÿ‘‹'),
        ],
      ),
    ],
  ).run();
}

๐Ÿงฑ Core Concepts

Everything is a Box

In Atomify, every UI element inherits from Box. This atomic approach ensures consistency and composability:

// Text is a Box
Text('Hello World')

// Button is a Box  
Button(Text('Click me'), onClick: (e) => print('Clicked!'))

// Container is a Box that holds other Boxes
Container(
  children: [
    Text('Title'),
    Button(Text('Action')),
  ],
)

Reactive State Management

Atomify makes reactivity effortless with ReactiveRef and Reactive widgets:

void main() {
  final counterRef = ReactiveRef<int>(0);
  
  App(
    children: [
      Container(
        children: [
          Reactive<int>(
            ref: counterRef,
            builder: (count) => Text('Count: $count'),
          ),
          Button(
            Text('Increment'),
            onClick: (e) => counterRef.emit((counterRef.state ?? 0) + 1),
          ),
        ],
      ),
    ],
  ).run();
}

Built-in page routing that's simple yet powerful:

final pageRef = PageRef();

Page(
  ref: pageRef,
  pages: [
    Container(id: 'home', children: [Text('Home Page')]),
    Container(id: 'about', children: [Text('About Page')]),
  ],
)

// Navigate programmatically
pageRef.goTo('about');

๐ŸŽจ Styling

Atomify integrates seamlessly with the cssify package for type-safe CSS:

import 'package:atomify/atomify.dart';

List<Cssify> styles = [
    Cssify.create(".my-container", {
        "base": {
            "style": {
                "background-color": "#f0f0f0",
                "padding": "20px",
                "border-radius": "8px",
            },
            "state": {
                "hover": {
                    "background-color": "#e0e0e0",
                },
            }
        },
        "md": {
            "style": {
                "padding": "30px",
            }
        },
    })
];

useCss(styles);
Container(
  className: 'my-container',
  children: [
    Text('Styled content'),
  ],
);

๐Ÿ“ฆ Available Elements

Atomify provides a rich set of atomic elements:

  • Layout: Container, Box
  • Text: Text
  • Interactive: Button, Input, Link
  • Data: Table
  • Async: Async (for handling Future data)
  • Progress: Progress indicators
  • Reactive: Reactive (for state-driven UI)

๐Ÿงฉ Creating your own Box

To create your own custom Box, simply extend the Box class and implement the render method:

import 'package:atomify/atomify.dart';

class CustomBox extends Box {
  // Pass child 
  final Box? child;
  ... // Define any properties you need
  CustomBox({
    this.child,
    super.id,
    super.className,
    ... other properties,
  }): super(tag: 'custom-box');

  @override
  HTMLElement render() {
    final element = super.render();

    if(child != null) {
      element.append(child!.render());
    }

    return element;
  }
}



## ๐Ÿ—๏ธ Architecture

App โ”œโ”€โ”€ Container (Layout) โ”‚ โ”œโ”€โ”€ Text (Content) โ”‚ โ”œโ”€โ”€ Button (Interactive) โ”‚ โ””โ”€โ”€ Reactive (State-driven) โ”‚ โ””โ”€โ”€ Builder Function โ””โ”€โ”€ Page (Navigation) โ”œโ”€โ”€ Route 1 โ”œโ”€โ”€ Route 2 โ””โ”€โ”€ Route N


## ๐ŸŽฏ Real-World Example

```dart
import 'package:atomify/atomify.dart';

void main() {
  final todoRef = ReactiveRef<List<String>>([]);
  final inputRef = InputRef();

  App(
    children: [
      Container(
        className: 'todo-app',
        children: [
          Text('๐Ÿ“ Todo App', className: 'title'),
          
          Container(
            className: 'input-section',
            children: [
              Input(
                ref: inputRef,
                placeholder: 'Add a new task...',
              ),
              Button(
                Text('Add'),
                onClick: (e) {
                  final value = inputRef.value;
                  if (value.isNotEmpty) {
                    todoRef.value = [...todoRef.value, value];
                    inputRef.clear();
                  }
                },
              ),
            ],
          ),
          
          Reactive<List<String>>(
            ref: todoRef,
            builder: (todos) => Container(
              className: 'todo-list',
              children: todos.map((todo) => 
                Container(
                  className: 'todo-item',
                  children: [Text(todo)],
                )
              ).toList(),
            ),
          ),
        ],
      ),
    ],
  ).run(target: "#root", beforeRender: (){
    // Optional: Any setup before rendering
  });
}

๐Ÿ“š Philosophy

Atomify embraces the principle that simple tools create powerful applications. By focusing on:

  1. Atomic Design: Small, reusable components
  2. Reactive Patterns: Automatic UI updates from state changes
  3. Minimal API Surface: Less to learn, more to build
  4. Type Safety: Leverage Dart's strong typing

We enable developers to build robust web applications without the complexity traditionally associated with web frameworks.

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guide for details.

๐Ÿ“„ License

MIT License - see LICENSE for details.


Built with โค๏ธ and Dart
Making web development atomic, one component at a time.

Libraries

atomify