live_cell_extension 0.6.2 copy "live_cell_extension: ^0.6.2" to clipboard
live_cell_extension: ^0.6.2 copied to clipboard

Generates cell property accessors for classes annotated with CellExtension from the live_cells package.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:live_cells/live_cells.dart';
import 'package:live_cells/live_cells_ui.dart';

part 'main.g.dart';

/// A custom class
///
/// The [CellExtension] annotation tells live_cell_extension to generate an
/// extension on `ValueCell<Person>` which provides accessors for the class's
/// properties.
///
/// `mutable: true` tells live_cell_extension to also generated an extension
/// on `MutableCell<Person>` which provides accessors for the class's properties
/// that return `MutableCell`'s.
@CellExtension(mutable: true)
class Person {
  final String firstName;
  final String lastName;
  final int age;

  const Person({
    required this.firstName,
    required this.lastName,
    required this.age
  });

  String get fullName => '$firstName $lastName';

  /// This uses the equals function generated by CellExtension.
  @override
  bool operator ==(Object other) => _$PersonEquals(this, other);

  /// This uses the hashCode function generated by CellExtension.
  @override
  int get hashCode => _$PersonHashCode(this);
}

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends CellWidget {
  @override
  Widget build(BuildContext context) {
    // A cell to hold the person's details
    final person = MutableCell(const Person(
        firstName: '',
        lastName: '',
        age: 25
    ));

    ValueCell.watch(() {
      // This is to demonstrate that all observers of person are notified
      // when a property changes
      print('Person changed: ${person().fullName}');
    });

    return Scaffold(
      appBar: AppBar(
        title: const Text('CellExtension Demo'),
      ),
      body: Center(
        child: Column(
          children: [
            Flexible(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.all(10.0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      const Text(
                        'Person Details:',
                      ),
                      const SizedBox(height: 10),

                      // Notice it is not necessary to wrap the property cells
                      // in cell(...) or to store them in a local variable.

                      LiveTextField(
                        content: person.firstName,
                        decoration: const InputDecoration(
                          label: Text('First Name')
                        ),
                      ),
                      LiveTextField(
                        content: person.lastName,
                        decoration: const InputDecoration(
                            label: Text('Last Name')
                        ),
                      ),
                      NumberField(
                          value: person.age,
                          label: 'Age'
                      ),
                      const SizedBox(height: 20),
                      const Text(
                        'The following uses the cell holding the entire Person, person():',
                        style: TextStyle(
                          fontWeight: FontWeight.bold
                        ),
                      ),
                      const SizedBox(height: 10),
                      CellWidget.builder((context) => Text('${person().fullName} is ${person().age} years old.')),
                      const SizedBox(height: 20),
                      ElevatedButton(
                        child: const Text('Reset'),
                        onPressed: () {
                          person.value = const Person(
                              firstName: '',
                              lastName: '',
                              age: 25
                          );
                        },
                      ),
                      const SizedBox(height: 20),
                      const Text(
                        'The following uses the generated accessors:',
                        style: TextStyle(
                            fontWeight: FontWeight.bold
                        ),
                      ),
                      const SizedBox(height: 10),
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          const Text('person.firstName():'),
                          const Spacer(),
                          Text(person.firstName()),
                        ],
                      ),
                      const SizedBox(height: 5),
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          const Text('person.lastName():'),
                          const Spacer(),
                          Text(person.lastName()),
                        ],
                      ),
                      const SizedBox(height: 5),
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          const Text('person.age():'),
                          const Spacer(),
                          Text('${person.age()}'),
                        ],
                      ),
                      const SizedBox(height: 10),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// A text field for a number.
///
/// The value of the [value] cell is synchronized with the numeric input that is
/// entered by the user.
class NumberField extends CellWidget {
  final String label;
  final MutableCell<int> value;

  const NumberField({
    super.key,
    required this.label,
    required this.value
  });

  @override
  Widget build(BuildContext context) {
    final maybe = value.maybe();
    final content = maybe.mutableString();
    final error = maybe.error;

    return LiveTextField(
      content: content,
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
          errorText: error() != null
              ? 'Not a valid integer'
              : null
      ),
    );
  }
}
2
likes
100
points
120
downloads

Publisher

verified publishergutev.dev

Weekly Downloads

Generates cell property accessors for classes annotated with CellExtension from the live_cells package.

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

analyzer, build, live_cell_annotations, source_gen

More

Packages that depend on live_cell_extension