over_react 1.20.2

  • README.md
  • CHANGELOG.md
  • Installing
  • Versions
  • 96

OverReact

Pub Documentation Join the chat at https://gitter.im/over_react/Lobby

Build Status Test Coverage Strong Mode Compliant

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

Using it in your project

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.

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

     dependencies:
       over_react: ^1.20.1
    
  2. Add the over_react transformer to your pubspec.yaml.

     transformers:
       - over_react
       # Reminder: dart2js should come after any other transformers that touch Dart code
       - $dart2js
    

    Our transformer uses code generation to wire up the different pieces of your component declarations - and to create typed getters/setters for props and state.

  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>
         <script type="application/dart" src="your_app_name.dart"></script>
         <script src="packages/browser/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 library (and associated react libraries) into your_app_name.dart, and initialize React within your Dart application. Then build a custom component and mount / render it into the HTML element you created in step 3.

     import 'dart:html';
     import 'package:react/react.dart' as react;
     import 'package:react/react_dom.dart' as react_dom;
     import 'package:over_react/over_react.dart';
    
     main() {
       // Initialize React within our Dart app
       setClientConfiguration();
    
       // Mount / render your component.
       react_dom.render(Foo()(), querySelector('#react_mount_point'));
     }    
    
  5. Run pub serve in the root of your Dart project.

 

Running tests in your project

When running tests on code that uses our transformer (or any code that imports over_react), you must run your tests using Pub.

  1. Add the test/pub_serve transformer to your pubspec.yaml after the over_react transformer.

     transformers:
       - over_react
       - test/pub_serve:
           $include: test/**_test{.*,}.dart
       - $dart2js
    
  2. Use the --pub-serve option when running your tests:

     $ pub run test --pub-serve=8081 test/your_test_file.dart
    

    Note: 8081 is the default port used, but your project may use something different. Be sure to take note of the output when running pub serve to ensure you are using the correct port.

   

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 to our Pub transformer using an analogous annotation.

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

 

UiFactory

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

@Factory()
UiFactory<FooProps> Foo;

 

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.

@Props()
class FooProps extends UiProps {
  // ...
}

 

UiProps as a Map

@Factory()
UiFactory<FooProps> Foo;

@Props()
class FooProps extends UiProps {
  String color;
}

@Component()
class FooComponent extends UiComponent<FooProps> {
  // ...  
}

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

  props.color = '#66cc00';

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

/// You can 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

@Factory()
UiFactory<FooProps> Foo;

@Props()
class FooProps extends UiProps {
  String color;
}

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

    // Add props
    builder.id = 'the_best_foo';
    builder.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.

@State()
class FooState extends UiState {
  // ...
}

UiState is optional, and won’t be used for every component.

 

UiComponent

UiComponent is a subclass of react.Component, containing lifecycle methods and rendering logic for components.

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

 

Accessing and manipulating props / state within UiComponent

  • Within the UiComponent 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.
@Component()
class FooComponent extends UiStatefulComponent<FooProps, FooState> {
  @override
  getDefaultProps() => (newProps()
    ..color = '#66cc00'
  );

  @override
  getInitialState() => (newState()
    ..isActive = false
  );

  @override
  componentWillUpdate(Map newProps, Map newState) {
    var tNewState = typedStateFactory(newState);
    var tNewProps = typedPropsFactory(newProps);

    var becameActive = !state.isActive && tNewState.isActive;

    // Do something here!
  }

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

  void _handleButtonClick(SyntheticMouseEvent event) {
    _toggleActive();
  }

  void _toggleActive() {
    setState(newState()
      ..isActive = !state.isActive
    );
  }
}

   

Fluent-style component consumption

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 "ubiquitous" 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.

   

Component Formatting

A note on dart_style:

Currently, dart_style (dartfmt) decreases the readability of components built using OverReact's fluent-style. See https://github.com/dart-lang/dart_style/issues/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.
  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

     $ pub serve
    

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

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

 

Component Boilerplate Templates

  • VS Code Snippet Extension

  • Component Boilerplate

      import 'dart:html';
      import 'package:react/react.dart' as react;
      import 'package:react/react_dom.dart' as react_dom;
      import 'package:react/react_client.dart';
      import 'package:over_react/over_react.dart';
    
      @Factory()
      UiFactory<FooProps> Foo;
    
      @Props()
      class FooProps extends UiProps {
        // Props go here, declared as fields:
        bool isDisabled;
        Iterable<String> items;
      }
    
      @Component()
      class FooComponent extends UiComponent<FooProps> {
        @override
        Map getDefaultProps() => (newProps()
          // Cascade default props here
          ..isDisabled = false
          ..items = []
        );
    
        @override
        render() {
          // Return the rendered component contents here.
          // The `props` variable is typed; no need for string keys!
        }
      }
    
  • Stateful Component Boilerplate

      import 'dart:html';
      import 'package:react/react.dart' as react;
      import 'package:react/react_dom.dart' as react_dom;
      import 'package:react/react_client.dart';
      import 'package:over_react/over_react.dart';
    
      @Factory()
      UiFactory<BarProps> Bar;
    
      @Props()
      class BarProps extends UiProps {
        // Props go here, declared as fields:
        bool isDisabled;
        Iterable<String> items;
      }
    
      @State()
      class BarState extends UiState {
        // State goes here, declared as fields:
        bool isShown;
      }
    
      @Component()
      class BarComponent extends UiStatefulComponent<BarProps, BarState> {
        @override
        Map getDefaultProps() => (newProps()
          // Cascade default props here
          ..isDisabled = false
          ..items = []
        );
    
        @override
        Map getInitialState() => (newState()
          // Cascade initial state here
          ..isShown = true
        );
    
        @override
        render() {
          // Return the rendered component contents here.
          // The `props` variable is typed; no need for string keys!
        }
      }
    
  • Flux Component Boilerplate

      import 'dart:html';
      import 'package:react/react.dart' as react;
      import 'package:react/react_dom.dart' as react_dom;
      import 'package:react/react_client.dart';
      import 'package:over_react/over_react.dart';
    
      @Factory()
      UiFactory<BazProps> Baz;
    
      @Props()
      class BazProps extends FluxUiProps<BazActions, BazStore> {
        // Props go here, declared as fields.
        // `actions` and `store` are already defined for you!
      }
    
      @Component()
      class BazComponent extends FluxUiComponent<BazProps> {
        getDefaultProps() => (newProps()
          // Cascade default props here
        );
    
        @override
        render() {
          // Return the rendered component contents here.
          // The `props` variables is typed; no need for string keys!
          // E.g., `props.actions`, `props.store`.
        }
      }
    
  • Stateful Flux Component Boilerplate

      import 'dart:html';
      import 'package:react/react.dart' as react;
      import 'package:react/react_dom.dart' as react_dom;
      import 'package:react/react_client.dart';
      import 'package:over_react/over_react.dart';
    
      @Factory()
      UiFactory<BazProps> Baz;
    
      @Props()
      class BazProps extends FluxUiProps<BazActions, BazStore> {
        // Props go here, declared as fields.
        // `actions` and `store` are already defined for you!
      }
    
      @State()
      class BazState extends UiState {
        // State goes here, declared as fields.
      }
    
      @Component()
      class BazComponent extends FluxUiStatefulComponent<BazProps, BazState> {
        getDefaultProps() => (newProps()
          // Cascade default props here
        );
    
        @override
        Map getInitialState() => (newState()
          // Cascade initial state here
        );
    
        @override
        render() {
          // Return the rendered component contents here.
          // The `props` variables is typed; no need for string keys!
          // E.g., `props.actions`, `props.store`.
        }
      }
    

 

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>.
      @Factory()
      UiFactory<DropdownButtonProps> DropdownButton;
    

    Bad:

      /// Component Factory for a dropdown button component.
      @Factory()
      UiFactory<DropdownButtonProps> DropdownButton;
    

 

  • ALWAYS set a default / initial value for 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:

      @Props()
      DropdownButtonProps extends 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;
      }
    
      @State()
      DropdownButtonState extends UiState {
        /// Whether the [DropdownButton]'s child [DropdownMenu] is open.
        ///
        /// Initial: [DropdownButtonProps.initiallyOpen]
        bool isOpen;
      }
    
      @Component()
      DropdownButtonComponent
          extends UiStatefulComponent<DropdownButtonProps, DropdownButtonState> {
        @override
        Map getDefaultProps() => (newProps()
          ..isDisabled = false
          ..initiallyOpen = false
        );
    
        @override
        Map getInitialState() => (newState()
          ..isOpen = props.initiallyOpen
        );
      }
    

    Bad:

      @Props()
      DropdownButtonProps extends UiProps {
        bool isDisabled;
        bool initiallyOpen;
      }
    
      @State()
      DropdownButtonState extends UiState {
        bool isOpen;
      }
    
      @Component()
      DropdownButtonComponent
          extends UiStatefulComponent<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:

      @Props()
      DropdownButtonProps extends 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;
      }
    
      @State()
      DropdownButtonState extends UiState {
        /// Whether the [DropdownButton]'s child [DropdownMenu] is open.
        ///
        /// Initial: [DropdownButtonProps.initiallyOpen]
        bool isOpen;
      }
    

    Bad:

      @Props()
      DropdownButtonProps extends UiProps {
        bool isDisabled;
        bool initiallyOpen;
      }
    
      @State()
      DropdownButtonState extends UiState {
        bool isOpen;
      }
    

 

Common Pitfalls

Below you’ll find some common errors / issues that new consumers run into when building custom components.

Don’t see the issue you're having? Tell us about it.


null object does not have a method 'call'

ⓧ Exception: The null object does not have a method 'call'.

This error is thrown when you call a @Factory() function that has not been initialized due to the over_react transformer not running, you’ll get this error.

Make sure you’ve followed the setup instructions.


404 on .dart file

ⓧ GET http://localhost:8080/src/your_component.dart
ⓧ An error occurred loading file: http://localhost:8080/src/your_component.dart

When the over_react transformer finds something wrong with your file, it logs an error in Pub and causes the invalid file to 404. This ensures that when the transformer breaks, pub build will break, and you’ll know about it.

Check your pub serve output for errors.

   

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.

OverReact Changelog

1.20.1

Complete 1.20.1 Changeset

Misc

  • #133: Update logger name standard.

1.20.0

Complete 1.20.0 Changeset

New Features

  • #128: Add UiPropsMapView.

Misc

  • #129: Add CODEOWNERS file.

1.19.0

Complete 1.19.0 Changeset

Dependency Updates

  • #126: Update minimum Dart SDK version to 1.24.2.

New Features

  • #118: Add BuiltReduxUiComponent and BuiltReduxUiProps.
    • These classes are considered unstable and can be imported via import "package:over_react/experimental.dart";

Tech Debt

  • #126: Use dependency_validator.

1.18.1

Complete 1.18.1 Changeset

Bug fixes

  • Fix regression in prop_mixins.dart introduced by #119.

1.18.0

Complete 1.18.0 Changeset

Improvements

  • #177: Improve error message when UiState classes aren't set up properly.

New Features

  • #119: More convenient ubiquitous access of DOM/aria props.
  • #120: Transition in/out-specific config, test attributes.

1.17.0

Complete 1.17.0 Changeset

New Features

  • #115: Add 4-argument callback utils

1.16.2

Complete 1.16.2 Changeset

Bug fixes

  • #110: Revert bugfixes that can cause FluxUiComponent rendering regressions:
    • ~~#108: Fix case where setState and store trigger only result in one FluxUiComponent render~~
    • ~~#103: FluxUiComponent redraws only once when store triggers along with ancestor rerender.~~

1.16.1

Complete 1.16.1 Changeset

Bug fixes

  • #108: Fix case where setState and store trigger only result in one FluxUiComponent render

1.16.0

Complete 1.16.0 Changeset

Dependency Updates

  • w_common ^1.8.0 (was ^1.6.0)
  • w_flux ^2.9.0 (was ^2.7.1)

New Features

  • #104: Update UiComponent to implement DisposableManagerV6.

Improvements

  • #103: FluxUiComponent redraws only once when store triggers along with ancestor rerender.

Tech Debt

  • #105: Add warning for incorrect usage of getDartComponent.

 

1.15.1

Complete 1.15.1 Changeset

Tech Debt

  • #97: Improve some documentation comments.
  • #95: Move internal test utils to over_react_test, and consume them.

 

1.15.0

Complete 1.15.0 Changeset

New Features

  • #88: Add validateProps method to UiComponent
    • Will automatically validate props annotated with @requiredProp within componentWillMount and componentWillReceiveProps

Tech Debt

  • #94: Address deprecations from package:test
  • #98: Fix misleading typo in overridden parameter name

Misc

 

1.14.0

Complete 1.14.0 Changeset

Dependency Updates

  • react ^3.4.3 (was ^3.4.1)
  • w_common ^1.6.0 (new)

New Features

  • #91: Implement DisposableManagerV3 for UiComponent
    • Assists with cleaning up streams and other data structures that won't necessarily be garbage collected without some manual intervention.

Misc

  • #92: Update prop error message to make it more DDC friendly

 

1.13.0

Complete 1.13.0 Changeset

Dependency Updates

  • #89: quiver >=0.21.4 <0.26.0 (was >=0.21.4 <0.25.0)

New Features

  • #87: Make DomProps/SvgProps implement UiProps for more convenient DDC typing

Misc

  • #86: Get tests passing using the DDC
  • #83: Use over_react_test

 

1.12.1

Complete 1.12.1 Changeset

Bug fixes

  • Bump min source_span to version w/ SourceFile.fromString

 

1.12.0

Complete 1.12.0 Changeset

Strong Mode / Dart Dev Compiler

  • #81: Make transformer output strong mode clean.
  • #82: Implement workarounds necessary to make OverReact-based code able to be compiled by the Dart Dev Compiler ("DDC").

 

1.11.2

Complete 1.11.2 Changeset

Bug Fixes

  • e805b7: Null-coalesce isDisposedOrDisposing to ease consumer test breakages.

 

1.11.1

Complete 1.11.1 Changeset

Bug Fixes

  • Revert #77: Update FluxUiComponent subscriptions when new props are received.
    • Reverted since this broke subclasses that weren't calling super in lifecycle methods componentWillReceieveProps and componentDidUpdate
    • Keep @mustCallSuper annotations from this changeset

 

1.11.0

Complete 1.11.0 Changeset

New Features

Bug Fixes

  • #77: Update FluxUiComponent subscriptions when new props are received.

Tech Debt Paid

  • #75: Audit the lib for any memory leak sources, and fortify it against future ones.

Misc

  • #72: Add logging message when a race condition causes BatchedRedraws to mount a FluxUiComponent asynchronously after the store has already been disposed.
    • Thanks @tomconnell-wf!

 

1.10.0

Complete 1.10.0 Changeset

Improvements

  • #69: New top-level getSelectionStart function to normalize selectionStart across browsers for both TextInputElements and TextAreaElements

Tech Debt Paid

  • #68: Declare explicitly-used transitive imports in pubspec.yaml
  • #70: Don't run ValidationUtil-related tests in dart2js

 

1.9.2

Complete 1.9.2 Changeset

Dependency Updates

  • analyzer >=0.26.1+3 <0.31.0 (was >=0.26.1+3 <0.30.0)

 

1.9.1

Complete 1.9.1 Changeset

Bug Fixes

  • #66: Fix regression with transitions not completing in consumers of AbstractTransitionComponent that don't call super.componentDidMount

 

1.9.0

Complete 1.9.0 Changeset

Improvements

  • #60: Provide easy access to DOM node in ValidationUtil.warn messages
  • #61: Export some react library members and add capturing event handlers
    • Export setClientConfiguration and ReactElement
    • Export all Synthetic*Event classes
    • Add capturing event handlers supported by ReactJS

Bug Fixes

  • #58: Fix issue with the transitionend warning (added via #55) sometimes firing when it shouldn't
  • #59: Ensure AbstractTransitionComponent does not call setState while in the process of unmounting
    • Thanks @joshbeam-wf!!!
  • #65 Work around Dart 1.23 strong mode issue with MapViewMixin

 

1.8.0

Complete 1.8.0 Changeset

Bug Fixes

  • #54: Fix strong mode warning
  • #55: Fix issue with AbstractTransitionComponent causing components to hang when the transitionend event never fires.

 

1.7.0

Complete 1.7.0 Changeset

Deprecations

  • #51: Deprecate the @Required() annotation since it conflicts with the meta package. Replaced by:
    • arguments to the Accessor annotation:

        @Accessor(isRequired: true, isNullable: true, requiredErrorMessage: 'foo')
      
    • shorthand aliases: @requiredProp/@nullableRequiredProp

Bug Fixes

  • #52: Eliminate dart2js warnings on component props classes

 

1.6.0

Complete 1.6.0 Changeset

  • #48: Improved getProps() functionality.
    • Allows you to traverse wrapper components by setting the named parameter traverseWrappers to true.

 

1.5.0

Complete 1.5.0 Changeset

Improvements

  • #46: Add ResizeSensorProps.quickMount flag for better performance when sensors are mounted often
  • Make getProp, getProps, and modifyProps conditional based on the named parameter shouldAdd/shouldModify.

Dependency Updates

  • Add missing quiver dependency (now depends on quiver >=0.21.4 <0.25.0)
  • Broaden analyzer dependency range to >=0.26.1+3 <0.30.0 (was >=0.26.1+3 <0.28.0)

 

1.4.0

Complete 1.4.0 Changeset

#40: Sync changes from original private repo library

This is the last time we'll do this - as the original library has now been completely switched over to use over_react

  • Switched dependency from browser_detect to our new platform_detect library!

  • Improved toString method of DebugFriendlyConstant.

  • Improved setSelectionRange polyfill to avoid https://github.com/dart-lang/sdk/issues/22967

  • Added typedef for ElementCallback and ResizeSensorHandler.

  • Added newStyleFromProps utility function.

  • Added getPropKey utility function.

    • Allows you to get a namespaced prop key dynamically!

Miscellaneous

  • #28: Run unit tests in dart2js on CI
  • #37: Update formatting guidelines WRT dartfmt and trailing commas

 

1.3.0

Complete 1.3.0 Changeset

React JS Upgrade

We are now on Gitter!

 

1.2.0

Complete 1.2.0 Changeset

Strong Mode

  • #15: Make over_react code "strong mode" compliant!
    • We will be working in the near future to make the code generated by our transformer compliant as well.

Dependency Updates

  • #23: Update minimum Dart SDK version to 1.19.1.
  • #15: Update minimum react package version to 3.0.1.

Bug Fixes

Documentation

 

1.1.1

Complete 1.1.1 Changeset

  • #6: Add contributor documentation.
  • #7: Allow "unsupported" units to be passed to the toRem and toPx functions.

 

1.1.0

Complete 1.1.0 Changeset

New Features

  • #10: Add FluxUiComponent and FluxUiStatefulComponent.
    • Enables consumers to build UI components with a uni-directional data flow via the w_flux library.

Misc

  • #8: Add a stateful UI component demo.
  • #9: Fix CI build fragility.

 

1.0.2

Complete 1.0.2 Changeset

  • #5: Add some Bootstrap UI components to web/ to demonstrate what can be built using OverReact.

 

1.0.1

Complete 1.0.1 Changeset

  • Add test coverage for the constants, dom_util, guid_util and event_helpers libraries.

 

1.0.0

Initial public release of the library.

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  over_react: "^1.20.2"

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:over_react/over_react.dart';
        
Version Uploaded Documentation Archive
1.20.2 Feb 16, 2018 Go to the documentation of over_react 1.20.2 Download over_react 1.20.2 archive
1.20.1 Jan 30, 2018 Go to the documentation of over_react 1.20.1 Download over_react 1.20.1 archive
1.20.0 Jan 8, 2018 Go to the documentation of over_react 1.20.0 Download over_react 1.20.0 archive
1.19.0 Dec 8, 2017 Go to the documentation of over_react 1.19.0 Download over_react 1.19.0 archive
1.18.1 Oct 18, 2017 Go to the documentation of over_react 1.18.1 Download over_react 1.18.1 archive
1.18.0 Oct 17, 2017 Go to the documentation of over_react 1.18.0 Download over_react 1.18.0 archive
1.17.0 Sep 28, 2017 Go to the documentation of over_react 1.17.0 Download over_react 1.17.0 archive
1.16.2 Aug 16, 2017 Go to the documentation of over_react 1.16.2 Download over_react 1.16.2 archive
1.16.1 Aug 14, 2017 Go to the documentation of over_react 1.16.1 Download over_react 1.16.1 archive
1.16.0 Aug 14, 2017 Go to the documentation of over_react 1.16.0 Download over_react 1.16.0 archive

All 35 versions...

Analysis

This feature is new.
We welcome feedback.
More details: scoring.

We analyzed this package, and provided a score, details, and suggestions below.

  • completed on Feb 16, 2018
  • Dart: 2.0.0-dev.20.0
  • pana: 0.10.1

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
92 / 100
Health:
Code health derived from static analysis. [more]
99 / 100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100 / 100
Overall score:
Weighted score of the above. [more]
96

Platforms

Detected platforms: web

Primary library: package:over_react/over_react.dart with components: html, js.

Suggestions

  • Maintain an example.

    Create a short demo in the example/ directory to show how to use this package. Common file name patterns include: main.dart, example.dart or you could also use over_react.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.24.2
analyzer >=0.30.0 <0.31.0 0.30.0+4 0.31.1
barback ^0.15.0 0.15.2+14
built_redux >=6.1.0 <8.0.0 7.3.5
built_value ^4.2.0 4.6.1 5.2.0
js ^0.6.0 0.6.1
logging >=0.11.3+1 <1.0.0 0.11.3+1
meta ^1.0.4 1.1.2
path ^1.4.1 1.5.1
platform_detect ^1.3.2 1.3.3
quiver >=0.21.4 <0.26.0 0.25.0 0.28.0
react ^3.4.3 3.6.0 4.2.0
source_span ^1.4.0 1.4.0
transformer_utils ^0.1.1 0.1.3
w_common ^1.8.0 1.11.1
w_flux ^2.7.1 2.9.4
Transitive dependencies
args 1.3.0
async 2.0.3 2.0.4
browser 0.10.0+2
build 0.11.2 0.12.0+1
built_collection 3.0.4
charcode 1.1.1
cli_util 0.1.2+1
collection 1.14.5
convert 2.0.1
crypto 2.0.2+1
csslib 0.14.1
dart_style 1.0.9+1
fixnum 0.10.7
front_end 0.1.0-alpha.4.1 0.1.0-alpha.10
glob 1.1.5
html 0.13.2+2
isolate 1.1.0
kernel 0.3.0-alpha.1.1 0.3.0-alpha.10
matcher 0.12.1+4
package_config 1.0.3
plugin 0.2.0+2
pool 1.3.4
pub_semver 1.3.2
stack_trace 1.9.2
string_scanner 1.0.2
typed_data 1.1.5
utf 0.9.0+4
watcher 0.9.7+7
yaml 2.1.13
Dev dependencies
build_runner ^0.5.0
built_value_generator ^4.2.0
coverage ^0.7.2
dart_dev ^1.7.6
dependency_validator ^1.0.0
mockito ^0.11.0
over_react_test ^1.2.0
source_gen ^0.7.2+1 0.7.5+1
test ^0.12.24