rivership 0.1.2 copy "rivership: ^0.1.2" to clipboard
rivership: ^0.1.2 copied to clipboard

An opinionated infrastructure package for use with hooks_riverpod.

Rivership #

Pub Version Coverage

Rivership is a set of opinionated tools that will get you shipping your Flutter app in no time if you are using riverpod and flutter_hooks.

Installation 💻 #

Install via dart pub add or flutter pub add:

dart pub add rivership

What's included 📦 #

Rivership includes a diverse set of hooks, type extensions, and utilities that will help you build your app faster and more efficiently. Everything is documented extensively, but here's a quick overview over the highlights:

Hooks #

useTweenAnimation

A super helpful hook that lets you use the power of TweenAnimationBuilder without any nesting.

final bool isActive;

Widget build(BuildContext context, WidgetRef ref) {
    // This will start at 0 and animate to 1 when isActive is true.
    // It will also keep animating each transition after that.
    final scale = useTweenAnimation<double>(
        Tween(begin: 0.0, end: isActive ? 1.0 : 0.0),
    );
    return Transform.scale(
        scale: scale,
        child: const Text('Hello World'),
    );
}

For even terser code, you can use the useTweenedValue convenience hook, that will initialize the Tween for you:

final bool isActive;

Widget build(BuildContext context, WidgetRef ref) {
    // This will automatically animate each transition when changing isActive.
    final scale = useTweenedValue<double>(isActive ? 1.0 : 0.0);
    return Transform.scale(
        scale: scale,
        child: const Text('Hello World'),
    );
}    

useDelayed

A hook that will help you model delayed UI changes in a declarative way. This can be super helpful for all kinds of animations, popovers, toasts, etc.

Let's say for example that we want to color a counter text red for 1 second every time its value changes.

final int value;

Widget build(BuildContext context, WidgetRef ref) {
    // This will restart with true every time value changes.
    final isRed = useDelayed(
        delay: const Duration(seconds: 1),
        before: true,
        after: false,
        keys: [value],
    );
    return Text(
        'Value: $value', 
        style: TextStyle(color: isRed ? Colors.red : Colors.black),
    );
}

If you don't want the text to start red, but instead only color it when value changes for the first time, you can set startDone to true:

final isRed = useDelayed(
    delay: const Duration(seconds: 1),
    before: true,
    after: false,
    startDone: true,
    keys: [value],
);

usePage

A hook that will return the current page from a given PageController which can help you achieve complex animations and transitions in PageViews.

Widget build(BuildContext context, WidgetRef ref) {
    final pageController = usePageController();
    final page = usePage(pageController);
    return Text('Current page: $page');
}

[!WARNING] Be mindful of rebuilds Similar to hooks like useAnimation, this hook will trigger a rebuild on every frame while the page is being dragged or animating. Make sure to call this from a widget that is cheap to rebuild, ideally a leaf of your widget tree.

Design Utilities #

Rivership includes a few helper tools for working with Colors and other UI properties.

SimpleWidgetStates

A subclass of WidgetStateProperty that purposefully doesn't trades flexibility for simplicity. Simply define states like this:

return TextButton(
    style: TextButton.styleFrom(
        color: SimpleWidgetStates.from(
            normal: Colors.blue,
            pressed: Colors.blue[800],
            disabled: Colors.grey,
        ),
    ),
    child: Text("Button"),
    onPressed: () {},
);

The values you don't pass will fall back to those you did pass, so you can define only the states you need.