Skip to main content

Hello World Guide: A Counter App with Parabeac

Welcome! This is our Hello World Guide to building with Parabeac. This guide assumes you know a little bit about Flutter and bloc and that you are set up on either Parabeac Nest or parabeac_core. Follow the guide below or watch this videoTODO!

If you're familiar with Flutter, you probably know about the sample Counter App. We're going to build exactly that but with Parabeac.

If you have any trouble with this guide feel free to reach out to us on our Discord Server or if you have ad-blocker turned off you can access the intercom chat button on the bottom right of this screen.

Step 1. Duplicate sample Figma file into your Figma Account:

https://www.figma.com/file/Ysnjcij14HaE98ucq1iwW1/Parabeac-Counter-App-Demo?node-id=0%3A1

Duplicate Figma File GIF

Step 2. Generate the code from the Figma file using Parabeac Nest or parabeac_core

If you're using Parabeac Nest, follow our guide on creating a project with Parabeac Nest.

If you're using parabeac_core, follow the guide on the README.

Step 3. Open up the codebase with VSCode or your favorite IDE

VSCode Image

Step 4. Install Flutter Packages

Run flutter pub get in your terminal within the counter_app repo.

Step 5. Update main.dart

In main.dart, change the home property of the MaterialApp to MyAppScreen() & import the widget with the following:

Your import should look something like this: import 'package:counter_app/screens/page_1/my_app_screen.g.dart';

The rest of the file should look like the following:

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

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: 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: MyAppScreen(),
);
}
}

Step 6.

At this point, we can run flutter run and see the visual output. Now we need to make it functional.

First let's add the flutter_bloc package to the pubspec.yaml file. At the time of this writing the latest version is:

flutter_bloc: ^8.0.0

In your pubspec.yaml you should now see:

dependencies:
auto_size_text: 3.0.0
flutter_bloc: ^8.0.0
flutter:
sdk: flutter

Lastly, run flutter pub get to install the bloc package.

Step 7. Create the model and logic

Next let's create a folder in lib/ called model/. Inside of our newly created folder model/ let's add a dart file called counter_cubit.dart. At this point our folder structure should look like the following:

Counter Cubit Folder Structure

We can now open counter_cubit.dart and create a simple Cubit that increments a state value with type int which should start at 0.

Insert the following code:

import 'package:flutter_bloc/flutter_bloc.dart';

class CounterCubit extends Cubit<int> {
CounterCubit({
int initialState = 0,
}) : super(initialState);

void increment() => emit(state + 1);
}

Step 8. Wrap the screen with the new bloc provider.

Now that we have the cubit, we can now enable all widgets below MyAppScreen to have access to it.

In main.dart, import the flutter_bloc import 'package:flutter_bloc/flutter_bloc.dart';

Then wrap MyAppScreen in a bloc provider with the CounterCubit we just created in Step 7.

@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: BlocProvider(
create: (BuildContext context) => CounterCubit(),
child: MyAppScreen(),
));

Now any child widget of MyAppScreen can access the CounterCubit.

Step 9. Leverage <custom> tags

As a developer, you don't want to modify the .g.dart files because these are made to be continuously regenerated as we make design changes to the Figma file.

However, if you take a look at the Figma file, you'll see that we labeled 2 items in here with the <custom> tag. Custom Figma Image

This outputs two files to the controller/tag/ folder. (counter_button_custom.dart, counter_value_holder_custom.dart)

Both files contain the boilerplate code that Parabeac generates to enter slots for the developer to add logic. Here we can communicate to the CounterCubit.

Step 10. Implement the Counter Button

From the files in controller/tag/, let's open counter_button_custom.dart. In here we are going to want to wrap widget.child with a GestureDetector.

The onTap: functionality should communicate to the CounterCubit and call the increment() function. Your build function in counter_button_custom.dart should look like the following:

class _CounterButtonState extends State<CounterButton> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
context.read<CounterCubit>().increment();
});
},
child: widget.child,
);
}

Don't forget to import import 'package:flutter_bloc/flutter_bloc.dart';

Step 11. Capturing the counter value.

From the files in controller/tag/, we now want to capture the state value in counter_value_holder_custom.dart. In here, we see widget.child, and we want to send values to this widget. To do this, we will want to take a look at the generated code in screens/page_1/my_app_screen.g.dart, find the reference call to CounterValueHolder() and copy it's child which is:

Generated Code Copy

We can reuse the child component call to CounterValueText. but instead of providing the value '0' to CounterValueText we will provide it the state value from the CounterCubit. Remember, we don't want to touch the my_app_screen.g.dart because future changes will be overidden from the design file. Head back over to controller/tag/counter_value_holder_custom.dart and add the following code:

Note: The reason we added a LayoutBuilder is because generated components must be sent constraints to support the proper constraint information provided by the design file.

class _CounterValueHolderState extends State<CounterValueHolder> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return CounterValueText(
constraints,
value: context.watch<CounterCubit>().state.toString(),
);
});
}
}

Step 12: Run the code!

Run flutter run. You should now see a functioning app!!!