• Stars
    star
    420
  • Rank 99,395 (Top 3 %)
  • Language
    Dart
  • License
    Other
  • Created over 7 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A library for building statically-typed React UI components using Dart.

OverReact

A library for building statically-typed React UI components using Dart.

This library also exposes OverReact Redux, which has its own documentation.

Pub Documentation OverReact Analyzer Plugin (beta) Join the gitter chat

Dart CI


Migration Guides

Building Components With Null Safety

Version 5.0.0 introduces support for null safety. Full documentation about building components using null safe over_react is coming soon!

UiComponent2 / Component Boilerplate Migration

There have been a lot of fantastic improvements in this library recently, all of which require some action on your part if you have existing components built prior to the 3.1.0 release of OverReact. We've done everything we can to make the migrations as painless as possible - with the vast majority of changes being handled by some codemod scripts you can run in your libraries locally. As always, if you encounter issues while working through the migration, you can reach out to us in our gitter chat, or open a new issue.

First, you should upgrade your components to UiComponent2. Check out the UiComponent2 Migration Guide to learn about the benefits of UiComponent2, the codemod script you can run, and other updates you may need to make manually.

Once you have migrated your components to UiComponent2, you're ready to start using the "v3" component boilerplate - which is a massive quality of life improvement for component authors! Check out the Component Boilerplate Migration Guide to learn about the benefits of the new boilerplate, the codemod script you can run, and other updates you may need to make manually.

More Migration Guides

  • BuiltRedux to Redux: A guide to transitioning to OverReact Redux from BuiltRedux.
  • Flux to Redux: A guide to how to transition from w_flux to OverReact Redux. This guide also introduces a new architecture, Influx, that can be used for incremental refactors.
  • Dart2 Migration: Documentation on the Dart 2 builder updates and how to transition componentry to Dart 2.
  • Null Safety: Documentation on how to migrate OverReact code to null safety.

   

Using OverReact

Prerequisites

  • Familiarize yourself with React JS

    Since OverReact is built atop React JS, we strongly encourage you to gain familiarity with it by reading some React JS tutorials first.

  • Familiarize yourself with Dart Web applications

    If you have never built a Web application in Dart, we strongly encourage you to gain familiarity with the core terminology, tools and boilerplate necessary to serve an application locally using Dart. Dart has fantastic documentation and tutorials to get you started.

  1. Add the over_react package as a dependency in your pubspec.yaml.

    dependencies:
      over_react: ^4.0.0
  2. Enable the OverReact Analyzer Plugin (beta), which has many lints and assists to make authoring OverReact components easier!

  3. Include the native JavaScript react and react_dom libraries in your app’s index.html file, and add an HTML element with a unique identifier where you’ll mount your OverReact UI component(s).

    <html>
      <head>
        <!-- ... -->
      </head>
      <body>
        <div id="react_mount_point">
          // OverReact component render() output will show up here.
        </div>
    
        <script src="packages/react/react.js"></script>
        <script src="packages/react/react_dom.js"></script>
    
        <!-- NOTE: "index" should correspond to the
             name of the `.dart` file that contains your `main()` entrypoint. -->
        <script type="application/javascript" defer src="index.dart.js"></script>
      </body>
    </html>

    Note: When serving your application in production, use packages/react/react_with_react_dom_prod.js file instead of the un-minified react.js / react_dom.js files shown in the example above.

  4. Import the over_react and react_dom libraries into index.dart. Then build some components and mount / render a React tree within the HTML element you created in the previous step by calling react_dom.render() within the main() entrypoint of your Dart application.

    Be sure to namespace the react_dom.dart import as react_dom to avoid collisions with UiComponent.render when creating custom components.

    import 'dart:html';
    import 'package:over_react/react_dom.dart' as react_dom;
    import 'package:over_react/over_react.dart';
    
    // Example of where the `Foo` component might be exported from
    import 'package:your_package_name/foo.dart';
    
    main() {
      // Mount / render your component/application.
      react_dom.render(
        Foo()(),
        querySelector('#react_mount_point'),
      );
    }
  5. Run webdev serve in the root of your Dart project.

Note: If you're not using the latest component boilerplate, you'll have to restart your analysis server in your IDE for the built types to resolve properly after the build completes. Unfortunately, this is a known limitation in the analysis server at this time.

Migrate your components to the latest component boilerplate to never worry about this again!

 

Running unit tests in your project

When running unit tests on code that uses the over_react builder (or any code that imports over_react), you must run your tests using the build_runner package.

Warning: Do not run tests via pub run build_runner test in a package while another instance of build_runner (e.g. pub run build_runner serve) is running in that same package. This workflow is unsupported by build_runner

  1. Run tests using the build_runner package, and specify the platform to be a browser platform. Example:

    $ pub run build_runner test -- -p chrome test/your_test_file.dart

OverReact Component Unit Test Examples

Below are links to a UI component from our example "Todo App", and its analogous tests that we've written for components we use in . We utilize the utilities found in our over_react_test library.

   

Anatomy of an OverReact component

If you are not familiar with React JS

Since OverReact is built atop React JS, we strongly encourage you to gain familiarity with it by reading this React JS tutorial first.

The over_react library functions as an additional "layer" atop the Dart react package which handles the underlying JS interop that wraps around React JS.

The library strives to maintain a 1:1 relationship with the React JS component class and API. To do that, an OverReact component is comprised of four core pieces that are each wired up via our builder.

  1. UiFactory
  2. UiProps
  3. UiState (optional)
  4. UiComponent2

 

UiFactory

UiFactory is a function that returns a new instance of a UiComponent2’s UiProps class.

UiFactory<FooProps> Foo = castUiFactory(_$Foo); // ignore: undefined_identifier

 

UiProps

UiProps is a Map class that adds statically-typed getters and setters for each React component prop. It can also be invoked as a function, serving as a builder for its analogous component.

mixin FooProps on UiProps {
  // ... the props for your component go here
  String bar;
  bool baz;
  List<int> bizzles;
}
    • Note: The builder generates a class with getters and setters overriding the fields you declare in your mixin, but you don't need to worry about that generated class. To use props from another mixin, simply mix it in! See "With other mixins" below for more information.

 

With other mixins

To compose props mixin classes, create a class alias that uses UiProps as the base and mix in multiple props mixins. The generated props implementation will then use it as the base class and implement the generated version of those props mixins.

UiFactory<FooProps> Foo = castUiFactory(_$Foo); // ignore: undefined_identifier

mixin FooPropsMixin on UiProps {
  String bar;
  bool baz;
  List<int> bizzles;
}

class FooProps = UiProps with FooPropsMixin, BarPropsMixin;

class FooComponent extends UiComponent2<FooProps> {
  // ...
}
Composition

The use-case for composing multiple props mixins into a single component props class is typically a component that renders another component, and therefore needs to expose the prop interface of that child component which will get forwarded via addUnconsumedProps.

Check out an example of props mixin component composition here

 

UiProps as a Map

UiFactory<FooProps> Foo = castUiFactory(_$Foo); // ignore: undefined_identifier

mixin FooProps on UiProps {
  String color;
}

class FooComponent extends UiComponent2<FooProps> {
  // ...
}

void bar() {
  FooProps props = Foo();

  props.color = '#66cc00';

  print(props.color); // #66cc00
  print(props);       // {FooProps.color: #66cc00}
}

/// You can also use the factory to create a UiProps instance
/// backed by an existing Map.
void baz() {
  Map existingMap = {'FooProps.color': '#0094ff'};

  FooProps props = Foo(existingMap);

  print(props.color); // #0094ff
}

 

UiProps as a builder

UiFactory<FooProps> Foo = castUiFactory(_$Foo); // ignore: undefined_identifier

mixin FooProps on UiProps {
  String color;
}

class FooComponent extends UiComponent2<FooProps> {
  ReactElement bar() {
    // Create a UiProps instance to serve as a builder
    FooProps builder = Foo();

    // Set some prop values
    builder
      ..id = 'the_best_foo'
      ..color = '#ee2724';

    // Invoke as a function with the desired children
    // to return a new instance of the component.
    return builder('child1', 'child2');
  }

  /// Even better... do it inline! (a.k.a fluent)
  ReactElement baz() {
    return (Foo()
      ..id = 'the_best_foo'
      ..color = 'red'
    )(
      'child1',
      'child2'
    );
  }
}

See fluent-style component consumption for more examples on builder usage.

 

UiState

UiState is a Map class (just like UiProps) that adds statically-typed getters and setters for each React component state property.

mixin FooState on UiState {
  // ...
}

UiState is optional, and won’t be used for every component. Check out the UiStatefulComponent boilerplate for more information.

  • Note: The builder will make the concrete getters and setters available from the mixin fields you author in a generated class. To mix state classes together, the mixin class should be used rather than the generated props class. See "With other mixins" above for more information.

 

UiComponent2

For guidance on updating to UiComponent2 from UiComponent, check out the UiComponent2 Migration Guide.

UiComponent2 is a subclass of react.Component2, containing lifecycle methods and rendering logic for components.

class FooComponent extends UiComponent2<FooProps> {
  // ...
}
  • This class provides statically-typed props via UiProps, as well as utilities for prop forwarding and CSS class merging.
  • The UiStatefulComponent2 flavor augments UiComponent2 behavior with statically-typed state via UiState.

 

Accessing and manipulating props / state within UiComponent2

  • Within the UiComponent2 class, props and state are not just Maps. They are instances of UiProps and UiState, which means you don’t need String keys to access them!
  • newProps() and newState() are also exposed to conveniently create empty instances of UiProps and UiState as needed.
  • typedPropsFactory() and typedStateFactory() are also exposed to conveniently create typed props / state objects out of any provided backing map.
UiFactory<FooProps> Foo = castUiFactory(_$Foo); // ignore: undefined_identifier

mixin FooProps on UiProps {
  String color;
  Function() onDidActivate;
  Function() onDidDeactivate;
}
mixin FooState on UiState {
  bool isActive;
}

class FooComponent extends UiStatefulComponent2<FooProps, FooState> {
  @override
  Map get defaultProps => (newProps()
    ..color = '#66cc00'
  );

  @override
  Map get initialState => (newState()
    ..isActive = false
  );

  @override
  void componentDidUpdate(Map prevProps, Map prevState, [dynamic snapshot]) {
    var tPrevState = typedStateFactory(prevState);
    var tPrevProps = typedPropsFactory(prevProps);

    if (state.isActive && !tPrevState.isActive) {
      props.onDidActivate?.call();
    } else if (!state.isActive && tPrevState.isActive) {
      props.onDidDeactivate?.call();
    }
  }

  @override
  dynamic render() {
    return (Dom.div()
      ..modifyProps(addUnconsumedDomProps)
      ..style = {
        ...newStyleFromProps(props),
        'color': props.color,
        'fontWeight': state.isActive ? 'bold' : 'normal', 
      }
    )(
      (Dom.button()..onClick = _handleButtonClick)('Toggle'),
      props.children,
    );
  }

  void _handleButtonClick(SyntheticMouseEvent event) {
    setState(newState()
      ..isActive = !state.isActive
    );
  }
}

   

Fluent-style component consumption

The OverReact analyzer plugin has many lints and assists to make authoring OverReact components easier!

In OverReact, components are consumed by invoking a UiFactory to return a new UiProps builder, which is then modified and invoked to build a ReactElement.

This is done to make "fluent-style" component consumption possible, so that the OverReact consumer experience is very similar to the React JS / "vanilla" react-dart experience.

To demonstrate the similarities, the example below shows a render method for JS, JSX, react-dart, and over_react that will have the exact same HTML markup result.

  • React JS:

    render() {
      return React.createElement('div', {className: 'container'},
        React.createElement('h1', null, 'Click the button!'),
        React.createElement('button', {
          id: 'main_button',
          onClick: _handleClick
        }, 'Click me')
      );
    }
  • React JS (JSX):

    render() {
      return <div className="container">
        <h1>Click the button!</h1>
        <button
          id="main_button"
          onClick={_handleClick}
        >Click me</button>
      </div>;
    }
  • Vanilla react-dart:

    render() {
      return react.div({'className': 'container'},
        react.h1({}, 'Click the button!'),
        react.button({
          'id': 'main_button',
          'onClick': _handleClick
        }, 'Click me')
      );
    }
  • OverReact:

    render() {
      return (Dom.div()..className = 'container')(
        Dom.h1()('Click the button!'),
        (Dom.button()
          ..id = 'main_button'
          ..onClick = _handleClick
        )('Click me')
      );
    }

    Let’s break down the OverReact fluent-style shown above

    render() {
      // Create a builder for a <div>,
      // add a CSS class name by cascading a typed setter,
      // and invoke the builder with the HTML DOM <h1> and <button> children.
      return (Dom.div()..className = 'container')(
    
        // Create a builder for an <h1> and invoke it with children.
        // No need for wrapping parentheses, since no props are added.
        Dom.h1()('Click the button!'),
    
        // Create a builder for a <button>,
        (Dom.button()
          // add a ubiquitous DOM prop exposed on all components,
          // which Dom.button() forwards to its rendered DOM,
          ..id = 'main_button'
          // add another prop,
          ..onClick = _handleClick
        // and finally invoke the builder with children.
        )('Click me')
      );
    }

   

DOM components and props

All react-dart DOM components (react.div, react.a, etc.) have a corresponding Dom method (Dom.div(), Dom.a(), etc.) in OverReact.

ReactElement renderLink() {
  return (Dom.a()
    ..id = 'home_link'
    ..href = '/home'
  )('Home');
}

ReactElement renderResizeHandle() {
  return (Dom.div()
    ..className = 'resize-handle'
    ..onMouseDown = _startDrag
  )();
}
  • OverReact DOM components return a new DomProps builder, which can be used to render them via our fluent interface as shown in the examples above.
    • DomProps has statically-typed getters and setters for all HTML attribute props.

    • The domProps() function is also available to create a new typed Map or a typed view into an existing Map. Useful for manipulating DOM props and adding DOM props to components that don’t forward them directly, or to access a DOM prop from a plain map in a lifecycle method as shown below.

      @override
      void componentDidUpdate(Map prevProps, Map prevState, [dynamic snapshot]) {
        // Say you want to compare the previous / current value of `DomProps.title` here...
        final titleChanged = domProps(prevProps).title != props.title;
      }

   

Component Formatting

A note on dart_style:

Currently, dart_style (dartfmt) decreases the readability of components built using OverReact's fluent-style. See dart-lang/dart_style#549 for more info.

We're exploring some different ideas to improve automated formatting, but for the time being, we do not recommend using dart_style with OverReact.

However, if you do choose to use dart_style, you can greatly improve its output by using trailing commas in children argument lists:

  • dart_style formatting:
return (Button()
  ..id = 'flip'
  ..skin =
      ButtonSkin.vanilla)((Dom.span()
  ..className = 'flip-container')((Dom.span()..className = 'flipper')(
    (Dom.span()
      ..className =
          'front-side')((Icon()..glyph = IconGlyph.CHEVRON_DOUBLE_RIGHT)()),
    (Dom.span()
      ..className =
          'back-side')((Icon()..glyph = IconGlyph.CHEVRON_DOUBLE_LEFT)()))));
  • dart_style formatting, when trailing commas are used:
return (Button()
  ..id = 'flip'
  ..skin = ButtonSkin.vanilla)(
  (Dom.span()..className = 'flip-container')(
    (Dom.span()..className = 'flipper')(
      (Dom.span()..className = 'front-side')(
        (Icon()..glyph = IconGlyph.CHEVRON_DOUBLE_RIGHT)(),
      ),
      (Dom.span()..className = 'back-side')(
        (Icon()..glyph = IconGlyph.CHEVRON_DOUBLE_LEFT)(),
      ),
    ),
  ),
);

Guidelines

To help ensure your OverReact code is readable and consistent, we've arrived at the following formatting rules.

  • ALWAYS place the closing builder parent on a new line.

    Good:

    (Button()
      ..skin = ButtonSkin.SUCCESS
      ..isDisabled = true
    )('Submit')

    Bad:

    (Button()
      ..skin = ButtonSkin.SUCCESS
      ..isDisabled = true)('Submit')
  • ALWAYS pass component children on a new line with trailing commas and 2 space indentation.

    Good:

    Dom.div()(
      Dom.span()('nested component'),
    )
    Dom.div()(
      Dom.span()('nested component A'),
      Dom.span()('nested component B'),
    )

    Bad:

    // Children are not on a new line; in most cases,
    // this makes it difficult to quickly determine nesting.
    Dom.div()(Dom.span()('nested component'), Dom.span()('nested component'))
    // With nested hierarchies, continuation indents can quickly result
    // in a "pyramid of Doom"
    Dom.div()(
        Dom.ul()(
            Dom.li()(
                Dom.a()('A link!')
            )
        )
    )
    // Omitting trailing commas makes it a pain to rearrange lines
    Dom.div()(
      Dom.span()('nested component A'),
      Dom.span()('nested component B')
    )
    Dom.div()(
      Dom.span()('nested component B') // ugh, need to add a comma here...
      Dom.span()('nested component A'),
    )
  • AVOID passing children within lists; lists should only be used when the number/order of the children are dynamic.

    Good:

    Dom.div()(
      Dom.span()('nested component'),
      Dom.span()('nested component'),
    )
    var children = [
      Dom.div()('List of Items:'),
    ]..addAll(props.items.map(renderItem));
    
    return Dom.div()(children)

    Bad:

    Dom.div()([
      (Dom.span()..key = 'span1')('nested component'),
      (Dom.span()..key = 'span2')('nested component'),
    ])
  • AVOID specifying more than one cascading prop setter on the same line.

    Good:

    (Dom.div()
      ..id = 'my_div'
      ..className = 'my-class'
    )()

    Bad:

    (Dom.div()..id = 'my_div'..className = 'my-class')()

Building custom components

Now that we’ve gone over how to use the over_react package in your project, the anatomy of a component and the DOM components that you get for free from OverReact, you're ready to start building your own custom React UI components.

  1. Start with one of the component boilerplate templates below (Or, use OverReact's code snippets for WebStorm/IntelliJ and VsCode).
  1. Fill in your props and rendering/lifecycle logic.

  2. Consume your component with the fluent interface.

  3. Run the app you’ve set up to consume over_react

    $ webdev serve

    That’s it! Code will be automatically generated on the fly by the builder!

Check out some custom component demos to get a feel for what’s possible!

 

Component Boilerplate Templates

  • Component Boilerplate

    import 'package:over_react/over_react.dart';
    part 'foo_component.over_react.g.dart';
    
    UiFactory<FooProps> Foo = castUiFactory(_$Foo); // ignore: undefined_identifier
    
    mixin FooProps on UiProps {
      // Props go here, declared as fields:
      bool isDisabled;
      Iterable<String> items;
    }
    
    class FooComponent extends UiComponent2<FooProps> {
      @override
      Map get defaultProps => (newProps()
        // Cascade default props here
        ..isDisabled = false
        ..items = []
      );
    
      @override
      dynamic render() {
        // Return the rendered component contents here.
        // The `props` variable is typed; no need for string keys!
      }
    }
  • Stateful Component Boilerplate

    import 'package:over_react/over_react.dart';
    part 'foo_component.over_react.g.dart';
    
    UiFactory<BarProps> Bar = castUiFactory(_$Bar); // ignore: undefined_identifier
    
    mixin BarProps on UiProps {
      // Props go here, declared as fields:
      bool isDisabled;
      Iterable<String> items;
    }
    
    mixin BarState on UiState {
      // State goes here, declared as fields:
      bool isShown;
    }
    
    class BarComponent extends UiStatefulComponent2<BarProps, BarState> {
      @override
      Map get defaultProps => (newProps()
        // Cascade default props here
        ..isDisabled = false
        ..items = []
      );
    
      @override
      Map get initialState => (newState()
        // Cascade initial state here
        ..isShown = true
      );
    
      @override
      dynamic render() {
        // Return the rendered component contents here.
        // The `props` variable is typed; no need for string keys!
      }
    }
  • Function Component Boilerplate

    import 'package:over_react/over_react.dart';
    part 'foo_component.over_react.g.dart';
    
    UiFactory<FooProps> Foo = uiFunction(
      (props) {
        // Set default props using null-aware operators.
        final isDisabled = props.isDisabled ?? false;
        final items = props.items ?? [];
    
        // Return the rendered component contents here.
        // The `props` variable is typed; no need for string keys!
        return Fragment()(
          Dom.div()(items),
          (Dom.button()..disabled = isDisabled)('Click me!'),
        );
      },
      // The generated props config will match the factory name.
      _$FooConfig, // ignore: undefined_identifier
    );
    
    mixin FooProps on UiProps {
      // Props go here, declared as fields:
      bool isDisabled;
      Iterable<String> items;
    }

 

Component Best Practices

  • ALWAYS write informative comments for your component factories. Include what the component relates to, relies on, or if it extends another component.

    Good:

    /// Use the `DropdownButton` component to render a button
    /// that controls the visibility of a child [DropdownMenu].
    ///
    /// * Related to [Button].
    /// * Extends [DropdownTrigger].
    /// * Similar to [SplitButton].
    ///
    /// See: <https://link-to-any-relevant-documentation>.
    UiFactory<DropdownButtonProps> DropdownButton = castUiFactory(_$DropdownButton); // ignore: undefined_identifier

    Bad:

    /// Component Factory for a dropdown button component.
    UiFactory<DropdownButtonProps> DropdownButton = castUiFactory(_$DropdownButton); // ignore: undefined_identifier

 

  • ALWAYS set a default / initial value for boolean props / state fields, and document that value in a comment.

    Why? Without default prop values for bool fields, they could be null - which is extremely confusing and can lead to a lot of unnecessary null-checking in your business logic.

    Good:

    mixin DropdownButtonProps on UiProps {
      /// Whether the [DropdownButton] appears disabled.
      ///
      /// Default: `false`
      bool isDisabled;
    
      /// Whether the [DropdownButton]'s child [DropdownMenu] is open
      /// when the component is first mounted.
      ///
      /// Determines the initial value of [DropdownButtonState.isOpen].
      ///
      /// Default: `false`
      bool initiallyOpen;
    }
    
    mixin DropdownButtonState on UiState {
      /// Whether the [DropdownButton]'s child [DropdownMenu] is open.
      ///
      /// Initial: [DropdownButtonProps.initiallyOpen]
      bool isOpen;
    }
    
    DropdownButtonComponent
        extends UiStatefulComponent2<DropdownButtonProps, DropdownButtonState> {
      @override
      Map get defaultProps => (newProps()
        ..isDisabled = false
        ..initiallyOpen = false
      );
    
      @override
      Map get initialState => (newState()
        ..isOpen = props.initiallyOpen
      );
    }

    Bad:

    mixin DropdownButtonProps on UiProps {
      bool isDisabled;
      bool initiallyOpen;
    }
    
    mixin DropdownButtonState on UiState {
      bool isOpen;
    }
    
    DropdownButtonComponent
        extends UiStatefulComponent2<DropdownButtonProps, DropdownButtonState> {
      // Confusing stuff is gonna happen in here with
      // bool props that could be null.
    }

 

  • AVOID adding props or state fields that don't have an informative comment.

    Good:

    mixin DropdownButtonProps on UiProps {
      /// Whether the [DropdownButton] appears disabled.
      ///
      /// Default: `false`
      bool isDisabled;
    
      /// Whether the [DropdownButton]'s child [DropdownMenu] is open
      /// when the component is first mounted.
      ///
      /// Determines the initial value of [DropdownButtonState.isOpen].
      ///
      /// Default: `false`
      bool initiallyOpen;
    }
    
    mixin DropdownButtonState on UiState {
      /// Whether the [DropdownButton]'s child [DropdownMenu] is open.
      ///
      /// Initial: [DropdownButtonProps.initiallyOpen]
      bool isOpen;
    }

    Bad:

    mixin DropdownButtonProps on UiProps {
      bool isDisabled;
      bool initiallyOpen;
    }
    
    mixin DropdownButtonState on UiState {
      bool isOpen;
    }

 

Ignore Ungenerated Warnings Project-Wide

To avoid having to add // ignore: uri_has_not_been_generated to each component library on the part/import that references generated code, ignore this warning globally within analysis_options.yaml:

 analyzer:
   errors:
     uri_has_not_been_generated: ignore

Alternatively, include workiva_analysis_options which ignores this warning by default.

 

Contributing

Yes please! (Please read our contributor guidelines first)

   

Versioning

The over_react library adheres to Semantic Versioning:

  • Any API changes that are not backwards compatible will bump the major version (and reset the minor / patch).
  • Any new functionality that is added in a backwards-compatible manner will bump the minor version (and reset the patch).
  • Any backwards-compatible bug fixes that are added will bump the patch version.

More Repositories

1

go-datastructures

A collection of useful, performant, and threadsafe Go datastructures.
Go
7,280
star
2

eva

A distributed database-system implementing an entity-attribute-value data-model that is time-aware, accumulative, and atomically consistent
Clojure
561
star
3

react-dart

Dart Bindings for React JS
JavaScript
409
star
4

frugal

Thrift improved
Go
139
star
5

built_redux

an implementation of redux written in dart that enforces immutability
Dart
126
star
6

dart_dev

Centralized tooling for Dart projects. Consistent interface across projects. Easily configurable.
Dart
74
star
7

dart_codemod

A library that makes it easy to write and run automated code modifications on a codebase.
Dart
60
star
8

dependency_validator

A tool to help you find missing, under-promoted, over-promoted, and unused dependencies.
Dart
56
star
9

state_machine

Easily create a finite state machine and define legal state transitions. Listen to state entrances, departures, and transitions.
Dart
56
star
10

go-rest

A Go library that makes it easy to build a flexible and (mostly) unopinionated REST API with little ceremony.
Go
48
star
11

opentelemetry-dart

Dart
45
star
12

furious

Fast and modular async task library for Google App Engine.
Python
37
star
13

w_flux

A Dart app architecture library with uni-directional data flow inspired by RefluxJS and Facebook's Flux.
Dart
25
star
14

morphe

A Clojure utility for defining and applying aspects to function definitions.
Clojure
25
star
15

w_transport

A platform-agnostic transport library for sending and receiving data over HTTP and WebSocket.
Dart
23
star
16

aws-lambda-fsm-workflows

A Python framework for developing finite state machine-based workflows on AWS Lambda.
Python
21
star
17

dart_to_js_script_rewriter

A pub transformer that Rewrites Dart script tags to JavaScript script tags, eliminating 404s and speeding up initial loads. Use when building for deployment.
Dart
21
star
18

go-hystrimp

An ergonomic implementation of Hystrix fault-tolerance principles for Go developers.
Go
19
star
19

w_module

Base module classes with a well defined lifecycle for modular Dart applications.
Dart
18
star
20

fluri

Fluri is a fluent URI library for Dart built to make URI mutation easy.
Dart
18
star
21

gae-financials

Simple demo app to illustrate developing real world applications on Google App Engine.
Python
18
star
22

platform_detect

A library for detecting browser and platform type and version.
Dart
17
star
23

thrift-nats

A library that adds support for using NATS as a Thrift RPC transport.
Go
14
star
24

wf-uicomponents

Mobile-optimized, composable UI components that support a rich HTML5 user experience.
JavaScript
13
star
25

wGulp

Opinionated Suite of Gulp Tasks for JavaScript and TypeScript projects.
JavaScript
12
star
26

utiliva

A collection of helpful little utilities for Clojure.
Clojure
11
star
27

webdev_proxy

A simple HTTP proxy for the webdev serve command (a tool authored by the dart team) that adds support for rewriting certain requests, namely rewriting 404s to instead serve the root index (/index.html). This allows developers to work on browser applications (like our own) that use HTML5 routing while still being able to refresh and/or navigate directly to deep links.
JavaScript
11
star
28

r_tree

A recursive RTree library written in Dart.
Dart
10
star
29

scip-dart

Dart
10
star
30

opentracing_dart

This library is the Open Tracing API written in Dart. It is intended for use both on the server and in the browser.
Dart
10
star
31

w_common

A collection of helpful utilities for use in Dart projects.
Dart
10
star
32

styleguide

9
star
33

pdfjs_dart

Dart bindings for Mozilla's PDF.js library
JavaScript
7
star
34

wf-common

A collection of helpful utilities for use in JavaScript projects.
JavaScript
6
star
35

flowgraph

A Clojure library for fast, concurrent, asynchronous data processing using directed graphs. Decursus supports cyclic graphs. Though it is not distributed, it does have primitive tools for minimizing communication overhead in the event that some processing steps involve calls to distributed resources.
Clojure
6
star
36

over_react_test

A library for testing OverReact components
Dart
6
star
37

dart_transformer_utils

Utilities relating to code generation, Dart analyzer, logging, etc. for use in Pub transformers.
Dart
6
star
38

w_service

Dart
5
star
39

react_testing_library

Dart bindings for the JS dom-testing-library and react-testing-library packages, which provide simple and complete DOM/React testing utilities that encourage good testing practices.
Dart
5
star
40

tesserae

A Clojure library that abstracts over promises, futures, delays, etc. with chaining and cancellations.
Clojure
4
star
41

w-mobile-kit

A Swift library containing various custom UI components to provide functionality outside of the default libraries.
Swift
4
star
42

wf-grunt

Opinionated Suite of Grunt Tasks for JavaScript and TypeScript projects.
JavaScript
4
star
43

goverge

A golang multi package coverage reporting tool.
Python
3
star
44

workiva_analysis_options

Workiva's shared Dart static analysis options
Dart
3
star
45

autoPaw

JavaScript
3
star
46

over_react_codemod

Codemods to help consumers of over_react automate the migration of UI component code.
Dart
3
star
47

paw

A touch / touch gesture simulation library for JavaScript.
JavaScript
3
star
48

sockjs-dart-client

A Dart client library for SockJS.
Dart
3
star
49

lsif_indexer

Dart
2
star
50

eva-client-service

The Eva client service is an Eva peer which exposes Eva functionality to other languages through a REST interface.
Java
2
star
51

font_face_observer

Load and unload fonts in the browser with a Promise based API. Simple, small and efficient. It will use the FontFace api if available, otherwise it falls back to a Dart port of https://github.com/bramstein/fontfaceobserver
Dart
2
star
52

sockjs_client_wrapper

A Dart wrapper around the SockJS Client. Uses the js Dart package to interop with the JS lib.
JavaScript
2
star
53

eva-catalog

Provides a central repository (and client) for handling the configuration maps used to connect to EVA
Clojure
1
star
54

lazy-tables

A set of tools for lazy relational algebra
Clojure
1
star
55

test_html_builder

Dart builder that generates HTML files from templates for dart tests.
Dart
1
star
56

abide

A command line tool to manage analysis_options.yaml and check if it abides by requirements.
Dart
1
star
57

barometer

A thin clojure wrapper over Coda Hale's metrics library for the JVM.
Clojure
1
star
58

ichnaie

A handful of Clojure utilities for easing project integration with the OpenTracing API
Clojure
1
star
59

recide

Provides utilities for defining standard ex-info forms, as well as the capacity for checking at compile-time that they are being used as intended
Clojure
1
star