<commit_before># coconut

A silly quest to find the Holy Grail of UI.

## Models

Coconut picks up the notion of *models* from MVC, which encapsulate the *state* in your business logic and define all operations that may affect it.

```haxe
import tink.pure.List;// <-- just an immutable list
import tink.core.Named;

class TodoItem implements Model {
  
  @:editable var completed:Bool = false;
  @:editable var description:String;

  @:constant var created:Date;

  static public function create(description:String) 
    return new TodoItem({ description: description, created: Date.now() });//Constructor is autogenerated

}

class TodoList implements Model {

  @:observable var items:List<TodoItem>;

  @:transition function add(description:String) 
    items = items.prepend();
  
  @:transition function clearCompleted() 
    items = items.filter(i => !i.isActive);

}

class TodoFilter implements Model {
  @:constant var options:List<Named<TodoItem->Bool>> = [
    new Named('All', _ => true),
    new Named('Active', TodoItem.isActive),
    new Named('Completed', TodoItem.isCompleted),
  ];

  @:observable var currentFilter:TodoItem->Bool = options.iterator().first().value;<commit_msg>Update model in doc<commit_after># coconut

A silly quest to find the Holy Grail of UI.

## Models

Coconut picks up the notion of *models* from MVC, which encapsulate the *state* in your business logic and define all operations that may affect it.

```haxe
import tink.pure.List;// <-- just an immutable list
import tink.core.Named;// <-- simple key-value pair
import coconut.data.Model;// <-- this is where magic comes from

class TodoItem implements Model {
  
  @:editable var completed:Bool = @byDefault false;
  @:editable var description:String;

  @:constant var created:Date = @byDefault Date.now();

  static public function create(description:String) 
    return new TodoItem({ description: description });//Constructor is autogenerated

  static public function isActive(item:TodoItem)
    return !item.completed;

  static public function isCompleted(item:TodoItem)
    return item.completed;

}

class TodoList implements Model {

  @:observable var items:List<TodoItem>;

  @:transition function add(description:String) 
    items = items.prepend(TodoItem.create(description));
  
  @:transition function clearCompleted() 
    items = items.filter(i => !i.completed);

}

class TodoFilter implements Model {
  @:constant var options:List<Named<TodoItem->Bool>> = [
    new Named('All', _ => true),
    new Named('Active', TodoItem.isActive),
    new Named('Completed', TodoItem.isCompleted),
  ];

  @:observable var currentFilter:TodoItem->Bool = options.iterator().next().value;
{'fraction_non_alphanumeric': 0.11404160475482912, 'fraction_numerical': 0.0, 'mean_word_length': 4.41851106639839, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '847836', 'n_tokens_mistral': 827, 'n_tokens_neox': 786, 'n_words': 252}