fst 0.4.0 copy "fst: ^0.4.0" to clipboard
fst: ^0.4.0 copied to clipboard

State tree interface implementation for Flutter + Flutter specific APIs

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:fst/fst.dart';

void main() {
  runApp(const CounterApp());
}

const $count = Context<int>(#count);

class IntCounter extends Impl<int> {
  final int initialValue;

  const IntCounter(super.n, [this.initialValue = 0]);

  @override
  int init(StateTreeNode n) => initialValue;

  void increment([covariant int delta = 1]) => value += delta;
  void decrement([covariant int delta = 1]) => value -= delta;
  void reset() => value = 0;
}

const $modifier = Context<bool>(#modifier);
const $modifierImpl = Context<ModifierImpl>(#modifier_impl);

class ModifierImpl extends Impl<bool> {
  const ModifierImpl(super.n);

  @override
  bool init(StateTreeNode n) => false;

  void onKey(RawKeyEvent e) {
    value = e.isShiftPressed;
  }

  @override
  void build(StateTreeNode n) {
    $modifier.of(n).provide(value);
    $modifierImpl.of(n).provide(this);
  }
}

class AppCounter extends IntCounter implements IncrementFABApi, ResetButtonApi {
  const AppCounter(super.n);

  @override
  void build(StateTreeNode n) {
    $count.of(n).provide(value);
    Home.$incrementEnabled.of(n).provide(value < 25);

    IncrementFAB.$api.of(n).provide(this);
    ResetButton.$api.of(n).provide(this);
  }
}

class CounterApp extends StatelessWidget {
  const CounterApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: mountMany([
        impl(ModifierImpl.new),
        impl(AppCounter.new),
        $count.listener((context, value) {
          if (value % 10 != 0 || value == 0) return;

          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Count is multiple of 10')),
          );
        }, mode: InvocationMode.postFrame),
        builder((context, n, child) {
          final focusNode = FocusNode();
          final impl = $modifierImpl.of(n).read();

          return RawKeyboardListener(
            focusNode: focusNode,
            autofocus: true,
            onKey: impl.onKey,
            child: child,
          );
        }),
        child(const Home()),
      ]),
    );
  }
}

class Home extends StateTreeWidget<void> {
  static const $incrementEnabled = Context<bool>(#increment_fab_enabled);

  const Home({super.key});

  @override
  Widget build(BuildContext context, StateTreeNode n) {
    final fab = $incrementEnabled.of(n).query((e) {
      if (!e) return null;
      return const IncrementFAB();
    });

    return Scaffold(
      appBar: AppBar(
        title: const Text('State Tree Example'),
        actions: const [
          ResetButton(),
        ],
      ),
      body: Center(
        child: StateTreeBuilder((context, n, _) {
          final count = n.watch($count);
          return Text('Count: $count');
        }),
      ),
      floatingActionButton: fab,
    );
  }
}

abstract interface class IncrementFABApi {
  void increment([int delta = 1]);
}

class IncrementFAB extends StateTreeWidget {
  static const $api = Context<IncrementFABApi>(#increment_fab_api);

  const IncrementFAB({super.key});

  @override
  Widget build(BuildContext context, StateTreeNode n) {
    final api = n.read($api);

    return FloatingActionButton(
      onPressed: () {
        final incrementBy10 = $modifier.of(n).read();
        api.increment(incrementBy10 ? 10 : 1);
      },
      child: const Icon(Icons.add),
    );
  }
}

abstract interface class ResetButtonApi {
  void reset();
}

class ResetButton extends StateTreeWidget {
  static const $api = Context<ResetButtonApi>(#reset_button_api);

  const ResetButton({super.key});

  @override
  Widget build(BuildContext context, StateTreeNode n) {
    final api = $api.of(n).read();

    return IconButton(
      onPressed: api.reset,
      icon: const Icon(Icons.refresh),
    );
  }
}
2
likes
130
points
29
downloads

Publisher

verified publisherlesnitsky.dev

Weekly Downloads

State tree interface implementation for Flutter + Flutter specific APIs

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, state_tree_interface

More

Packages that depend on fst