relation 3.1.0 copy "relation: ^3.1.0" to clipboard
relation: ^3.1.0 copied to clipboard

the stream representation of the relations of the entities and widget utilities

Relation #

Build Status Coverage Status Pub Version Pub Likes Pub popularity Flutter Platform

This package is part of the SurfGear toolkit made by Surf.

About #

The stream representation of the relations of the entities and widget utilities

Usage #

Main classes:

  1. StreamedAction 1.1 ScrollOffsetAction 1.2 TextEditingAction
  2. Builder 2.1 EntityStateBuilder 2.2 StreamedStateBuilder 2.3 TextfieldStateBuilder
  3. StreamedState
  4. EntityStreamedState

Actions #

StreamedAction #

It's wrapper over an action on screen. It may be a tap on button, text changes, focus changes and so on.

   SomeWidget(
     onTap: someAction.accept,
   )
    
   ...

   someAction.action.listen(doSomething);

ScrollOffsetAction #

The action that fires when the value changes when scrolling.

  testWidgets(
    'ScrollOffsetAction test',
    (WidgetTester tester) async {
      final action = ScrollOffsetStreamedAction((onChanged) {
        expect(1.0, onChanged);
      });

      await tester.pumpWidget(MaterialApp(
        title: 'Flutter Demo',
        home: Scaffold(
          appBar: AppBar(
            title: Text('test'),
          ),
          body: ListView(
            controller: action.controller,
            scrollDirection: Axis.vertical,
            children: <Widget>[
              Text('test'),
              Text('test'),
              Text('test'),
            ],
          ),
        ),
      ));

      action.controller.jumpTo(1.0);
    },
  );

TextEditingStreamedAction #

Currently experimental.
An action that fires when a text field receives new characters

  test('TextEditingAction test', () {
    final action = TextEditingAction((onChanged) {
      expect('test', onChanged);
    });
    action.controller.text = 'test';
  });

Builder #

Builders are widgets that listen to a change in a stream and provide new data to child widgets

StreamedStateBuilder #

Updates child widget when an answer arrives

 testWidgets(
    'StreamedStateBuilder test',
    (WidgetTester tester) async {
      final testData = StreamedState<String>('test');
      final streamedStateBuilder = StreamedStateBuilder<String>(
          streamedState: testData,
          builder: (context, data) {
            return Text(data);
          });
      await tester.pumpWidget(
        MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            body: streamedStateBuilder,
          ),
        ),
      );
      final textFinder = find.text('test');
      expect(textFinder, findsOneWidget);
    },
  );

EntityStateBuilder #

This builder has three states onResponse, onError, onLoading

 testWidgets(
    'StreamedStateBuilder accept test',
    (WidgetTester tester) async {
      final testData = EntityStreamedState<String>(EntityState(data: 'test'));

      final streamedStateBuilder = EntityStateBuilder<String>(
        streamedState: testData,
        child: (context, data) {
          return Text(data);
        },
      );

      await tester.pumpWidget(
        MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            body: streamedStateBuilder,
          ),
        ),
      );
      expect(streamedStateBuilder.streamedState.value.data, 'test');
      final testFinder = find.text('test');
      expect(testFinder, findsOneWidget);

      await testData.error();
    },
  );

  testWidgets(
    'StreamedStateBuilder error test',
    (WidgetTester tester) async {
      final testData = EntityStreamedState<String>();
      final streamedStateBuilder = EntityStateBuilder<String>(
        streamedState: testData,
        child: (context, data) {
          return Text('test');
        },
        errorChild: Text('error_text'),
      );

      unawaited(testData.error(Exception()));
      await tester.pumpWidget(
        MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            body: streamedStateBuilder,
          ),
        ),
      );

      final errorFinder = find.text('error_text');
      expect(errorFinder, findsOneWidget);
    },
  );

  testWidgets(
    'StreamedStateBuilder loading test',
        (WidgetTester tester) async {
      final testData = EntityStreamedState<String>();
      final streamedStateBuilder = EntityStateBuilder<String>(
        streamedState: testData,
        child: (context, data) {
          return Text('test');
        },
        loadingChild: Text('loading_child'),
      );

      unawaited(testData.loading());
      await tester.pumpWidget(
        MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            body: streamedStateBuilder,
          ),
        ),
      );

      final loadingFinder = find.text('loading_child');
      expect(loadingFinder, findsOneWidget);
    },
  );

TextFieldStateBuilder #

Wrapper over TextFieldStreamedState.
StateBuilder callback is triggered every time new data appears in the stream.

  testWidgets(
    'TextfieldStreamBuilder content test',
    (WidgetTester tester) async {
      final testData = TextFieldStreamedState('test');
      final textFieldStateBuilder = TextFieldStateBuilder(
          state: testData,
          stateBuilder: (context, data) {
            return Text('test');
          });

      await tester.pumpWidget(
        MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            body: textFieldStateBuilder,
          ),
        ),
      );

      final textFinder = find.text('test');
      expect(textFinder, findsOneWidget);
    },
  );

State #

StreamedState #

A state of some type wrapped in a stream dictates the widget's state

   yourStreamedState.accept(someData);
    
   ...
   
   StreamedStateBuilder<T>(
     streamedState: yourStreamedState,
     builder: (ctx, T data) => Text(data.toString()),
   );

EntityStreamedState #

A state that have download/error/content status

 dataState.loading();
 try {
    var content = await someRepository.getData();
    dataState.content(content);
 } catch (e) {
    dataState.error(e);
 }
 
 ...

 EntityStateBuilder<Data>(
      streamedState: dataState,
      child: (data) => DataWidget(data),
      loadingChild: LoadingWidget(),
      errorChild: ErrorPlaceholder(),
    );

Installation #

Add relation to your pubspec.yaml file:

dependencies:
  relation: ^3.0.0

You can use both stable and dev versions of the package listed above in the badges bar.

Changelog #

All notable changes to this project will be documented in this file.

Issues #

For issues, file directly in the main SurfGear repo.

Contribute #

If you would like to contribute to the package (e.g. by improving the documentation, solving a bug or adding a cool new feature), please review our contribution guide first and send us your pull request.

Your PRs are always welcome.

How to reach us #

Please feel free to ask any questions about this package. Join our community chat on Telegram. We speak English and Russian.

Telegram

License #

Apache License, Version 2.0

25
likes
130
pub points
78%
popularity

Publisher

verified publishersurf.ru

the stream representation of the relations of the entities and widget utilities

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, rxdart

More

Packages that depend on relation