{"id":21654690,"url":"https://github.com/localvoid/uix","last_synced_at":"2025-04-11T21:13:51.591Z","repository":{"id":28854775,"uuid":"32378802","full_name":"localvoid/uix","owner":"localvoid","description":"[UNMAINTAINED] Dart Web UI library","archived":false,"fork":false,"pushed_at":"2017-06-26T07:24:18.000Z","size":216,"stargazers_count":77,"open_issues_count":9,"forks_count":4,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-11T21:13:46.553Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/localvoid.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-17T07:47:12.000Z","updated_at":"2023-09-08T16:55:44.000Z","dependencies_parsed_at":"2022-08-29T06:50:43.361Z","dependency_job_id":null,"html_url":"https://github.com/localvoid/uix","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localvoid%2Fuix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localvoid%2Fuix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localvoid%2Fuix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localvoid%2Fuix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/localvoid","download_url":"https://codeload.github.com/localvoid/uix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480427,"owners_count":21110937,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T08:28:43.914Z","updated_at":"2025-04-11T21:13:51.570Z","avatar_url":"https://github.com/localvoid.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# uix\n\n[![Build Status](https://travis-ci.org/localvoid/uix.svg?branch=master)](https://travis-ci.org/localvoid/uix)\n[![Join the chat at https://gitter.im/localvoid/uix](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/localvoid/uix?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nLibrary to build Web User Interfaces in [Dart](https://dartlang.org)\ninspired by [React](http://facebook.github.io/react/).\n\n### Virtual DOM\n\nVirtual DOM simplifies the way to manage DOM mutations, just describe\nhow your Component should look at any point in time.\n\nuix library has a highly optimized virtual dom implementation,\n[see benchmarks below](#benchmarks).\n\n### Scheduler\n\nScheduler is responsible for running tasks that update visual\nrepresentation of the Components, and business logic of web app\nservices.\n\n### Misc\n\n- Automatic management of Dart\n[streams](https://www.dartlang.org/docs/tutorials/streams/) with\n`addSubscription(StreamSubscription s)`,\n`addTransientSubscription(StreamSubscription s)` methods. Transient\nsubscriptions simplifies the way to manage subscriptions the same way\nvirtual dom simplifies DOM mutations, just describe which dependencies\nshould be active at any point in time.\n\n```dart\n// Code from TodoMVC[Observable] example\n\n$Entry() =\u003e new Entry();\nclass Entry extends Component\u003cint\u003e {\n  updateState() {\n    _entry = entryStore.get(data);\n\n    // each time Component is invalidated, old subscription will be\n    // automatically canceled, so we just register a new one when\n    // something is changed.\n    addTransientSubscription(_entry.onChange.listen(invalidate));\n\n    return true;\n  }\n  ...\n}\n```\n\n- revisioned nodes for fast \"dirty checking\" of mutable data\nstructures. Just update revision when data is changed and check if\nview has an older revision, for example:\n\n```dart\nclass LineView extends Component\u003cRichLine\u003e {\n  List\u003cVNode\u003e _fragments;\n\n  set data(RichLine newData) {\n    if (identical(data, newData)) {\n      if (data.isNewer(this)) {\n        invalidate();\n      }\n    } else {\n      data_ = newData;\n      invalidate();\n    }\n  }\n  ...\n}\n```\n\n- Lifecycle control of children virtual nodes to implement complex\n  animations. For example:\n  [CssTransitionContainer](https://github.com/localvoid/uix_css_transition_container)\n\n- Mount on top of existing html\n  document. [Mount example](https://github.com/localvoid/uix/tree/master/example/mount)\n\n- Moving html nodes and components between different parents and\n  preserving internal state with Virtual DOM api using `Anchor`\n  objects. [Anchor example](https://github.com/localvoid/uix/tree/master/example/anchor)\n\n## Quick Start\n\nRequirements:\n\n - Dart SDK 1.9.1 or greater\n\n#### 1. Create a new Dart Web Project\n#### 2. Add uix library in `pubspec.yaml` file:\n\n```yaml\ndependencies:\n  uix: any\n```\n\n#### 3. Install dependencies\n\n```sh\n$ pub get\n```\n\n#### 4. Create `web/index.html` file:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n    \u003ctitle\u003eHello uix\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript type=\"application/dart\" src=\"main.dart\"\u003e\u003c/script\u003e\n    \u003cscript src=\"packages/browser/dart.js\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### 5. Create `web/main.dart` file:\n\n```dart\nlibrary main;\n\nimport 'dart:html' as html;\nimport 'package:uix/uix.dart';\n\n// Function to create new Box instances, it is used as an argument for\n// virtual nodes that represent components.\n// In the future, when metaclasses will be implemented in Dart, it\n// won't be necessary to create this functions. Right now it is just a\n// convention that will make it easier to migrate in the future by\n// removing '$' prefix in all 'vComponent' invocations.\n$Box() =\u003e new Box();\n\n// Component\u003cT\u003e type parameter is used to specify type of the input data\n// (props in React terms).\nclass Box extends Component\u003cString\u003e {\n  // Tag name of the root element for this Component. Default tag 'div'.\n  final tag = 'span';\n\n  // Each time when Component is invalidated (new data is passed,\n  // or invalidate() method is called), it will be updated during\n  // writeDom phase.\n  //\n  // API is designed this way intentionally to improve developer\n  // experience and get better stack traces when something is\n  // failing, that is why there is no method like render() in\n  // React.\n  updateView() {\n    // updateRoot method is used to update internal representation\n    // using Virtual DOM API.\n    //\n    // vRoot node is used to represent root element.\n    //\n    // Call operator is overloaded for all virtual nodes and is used\n    // to assign children, it accepts Lists, Iterables, VNodes and\n    // Strings.\n    updateRoot(vRoot()(\n      vElement('span')(data)\n    ));\n  }\n}\n\nclass Main extends Component\u003cString\u003e {\n  updateView() {\n    updateRoot(vRoot()([\n      vElement('span')('Hello '),\n      vComponent($Box, data: data)\n    ]));\n  }\n}\n\nmain() {\n  // Initialize uix library.\n  initUix();\n\n  final component = new Main()..data = 'uix';\n\n  // Inject component into document body.\n  injectComponent(component, html.document.body);\n}\n```\n\n## Examples\n\n- [Hello](https://github.com/localvoid/uix/tree/master/example/hello)\n- [Timer](https://github.com/localvoid/uix/tree/master/example/timer)\n- [Collapsable](https://github.com/localvoid/uix/tree/master/example/collapsable)\n- [Form](https://github.com/localvoid/uix_forms/tree/master/example)\n- [State Diff](https://github.com/localvoid/uix/tree/master/example/state_diff)\n- [Read/Write DOM Batching](https://github.com/localvoid/uix/tree/master/example/read_write_batching)\n- [Component Inheritance](https://github.com/localvoid/uix/tree/master/example/inheritance)\n- [SVG](https://github.com/localvoid/uix/tree/master/example/svg)\n- [Canvas](https://github.com/localvoid/uix/tree/master/example/canvas)\n- [Css Transition Container](https://github.com/localvoid/uix_css_transition_container/tree/master/example)\n- [TodoMVC (observable)](https://github.com/localvoid/uix_todomvc/)\n- [TodoMVC (persistent)](https://github.com/localvoid/uix_todomvc_persistent/)\n- [MineSweeper Game](https://github.com/localvoid/uix_minesweeper/)\n- [Snake Game](https://github.com/localvoid/uix_snake/)\n- [Dual N-Back Game](https://github.com/localvoid/dual_nback/)\n\n## VDom Benchmark\n\u003ca name=\"benchmarks\"\u003e\u003c/a\u003e\n\n- [Run](http://vdom-benchmark.github.io/vdom-benchmark/)\n\n## DBMonster Benchmark\n\n- [Run](http://localvoid.github.io/uix_dbmon/)\n- [Run](http://localvoid.github.io/uix_dbmon/classlist2) (compiled with [patched dart-sdk](https://code.google.com/p/dart/issues/detail?id=23012))\n\n## Server-Side rendering\n\nuix library with\n[simple tweaks](https://github.com/localvoid/uix_standalone) is fully\ncapable to render components on the server and mounting on top of the\nexisting html tree. Unfortunately Dart doesn't support any usable way\nto build uix Components this way. There are several proposals for\nConfigured Imports [1](https://github.com/lrhn/dep-configured-imports)\n[2](https://github.com/eernstg/dep-configured-imports)\n[3](https://github.com/munificent/dep-external-libraries/blob/master/Proposal.md)\nthat will solve some problems, but it is still not enough to provide a\ngood developer experience for users of this library. Conditional\ncompilation will be way much better to write \"isomorphic\" Components.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalvoid%2Fuix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocalvoid%2Fuix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalvoid%2Fuix/lists"}