diff --git a/docs/ff-concepts/adding-customization/cloud-functions.md b/docs/ff-concepts/adding-customization/cloud-functions.md index 4624842e..216a8971 100644 --- a/docs/ff-concepts/adding-customization/cloud-functions.md +++ b/docs/ff-concepts/adding-customization/cloud-functions.md @@ -3,7 +3,7 @@ slug: /concepts/custom-code/cloud-functions title: Cloud Functions description: Learn how to use Cloud Functions in your FlutterFlow app for serverless backend functionality. tags: [Cloud Functions, Serverless, Integration] -sidebar_position: 6 +sidebar_position: 7 keywords: [FlutterFlow, Cloud Functions, Serverless, Integration] --- diff --git a/docs/ff-concepts/adding-customization/common-examples.md b/docs/ff-concepts/adding-customization/common-examples.md new file mode 100644 index 00000000..a54b6b59 --- /dev/null +++ b/docs/ff-concepts/adding-customization/common-examples.md @@ -0,0 +1,348 @@ +--- +slug: /concepts/custom-code/common-examples +title: Common Examples +description: Learn about the common custom code examples and use it directly in your project. +tags: [Custom Actions, Custom Code] +sidebar_position: 6 +keywords: [FlutterFlow, Custom Actions, Customizations, Flutter, Dart, Pub.dev, Examples] +--- + +# Common Code Examples + +The custom code feature in FlutterFlow allows you to extend functionality by accessing generated classes and modifying global variables like App States and FlutterFlow themes. This guide covers common scenarios where you can leverage custom code to enhance your project by working directly with data models and other resources within your code. + +:::warning[Disclaimer] +Custom Functions cannot import new files or packages outside of the default dedicated imports. Therefore, most of the suggestions below that involve adding a new import will not work in Custom Functions due to this restriction. However, they will work for Custom Widgets and Custom Actions. + +For example, a new [**Custom Function**](custom-functions.md) typically includes the following packages and files. Your custom function code changes should use only these packages & files: + +```js +import 'dart:convert'; +import 'dart:math' as math; + +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:intl/intl.dart'; +import 'package:timeago/timeago.dart' as timeago; +import 'lat_lng.dart'; +import 'place.dart'; +import 'uploaded_file.dart'; +import '/backend/backend.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import '/backend/schema/structs/index.dart'; +import '/backend/schema/enums/enums.dart'; +import '/auth/firebase_auth/auth_util.dart'; +``` + +::: +### Accessing FlutterFlow Generated Classes + +FlutterFlow generates a complete Flutter codebase for you as you build apps in its platform. Part of this code includes custom classes that are designed to streamline common tasks and encapsulate reusable properties or logic. + +For example: + +- **Button Widgets:** FlutterFlow provides custom button classes like `FFButton` that come with built-in styling and behaviors. +- **Google Places:** The `FFPlace` class encapsulates properties of a Google Place, such as name, address, and coordinates. +- **File Uploads:** The `FFUploadedFile` class represents files uploaded to your app, encapsulating properties like the file name, bytes, and URL. + + +:::tip[What is a Class?] +In programming, a class is a blueprint for creating objects. It defines properties (data) and methods (functions) that belong to objects of that type. + +For example, + +- A `Car` class might have properties like `color` and `speed` and methods like `drive()` and `stop()`. +- In FlutterFlow, a class like `FFPlace` might have properties like `address` and `latLng`, and methods to manipulate or retrieve these values. +::: + +These custom FlutterFlow classes in the generated code are mostly prefixed with `FF` or `FlutterFlow`. If you need to access these classes in your custom code, simply type "FF" or "FlutterFlow" in the code editor to locate them quick. + + +![suggestions-dropdown.png](imgs/suggestions-dropdown.png) + +### Leveraging Components in Custom Widget + +:::warning[Static Components vs Dynamic] +Use this approach only when the component is a fixed element that does not change across different use cases. If the child component needs to change based on user choices, pass it directly [**as a parameter**](custom-widgets.md#creating-a-new-custom-widget). +::: + +In a **[Custom Widget](custom-widgets.md)**, you can integrate a previously built **[FlutterFlow Component](../../resources/ui/components/intro-components.md)** directly, saving you from recreating child content in code. For example, if you’re building a Custom Widget to display custom dialog boxes or bottom sheets using a package from +[pub.dev](custom-code.md#pubdev), you can simply return an existing Component created on the canvas, rather than coding a new one from scratch. + +:::tip[Imports] +When referencing a Component class in your code, FlutterFlow will automatically add the necessary import statement. +::: + + + +![return-widget-custom-code.png](imgs/return-widget-custom-code.png) + + +### Accessing FlutterFlow Theme in Custom Widget + +When building custom widgets, you often need to style parts of the widget, such as setting colors. Instead of using hardcoded color values, you can directly access the **FlutterFlow Theme**. This theme provides consistent styling across your app and reflects colors set by you or your project developer. + +To access theme colors in your custom widget, use the `FlutterFlowTheme.of(context)` method. This allows you to retrieve any theme property, such as the default `primary`, `primaryBackground`, or other custom-created colors, as well as text styles like `bodyLarge` or `bodyMedium`, ensuring that your custom widget aligns with the app’s overall theme. + +Here’s an example of how to use the primary color from FlutterFlow Theme in a custom widget: + +:::tip[Imports] +Ensure you import `import '../flutter_flow/flutter_flow_theme.dart';` when accessing `FlutterFlowTheme` in your custom widgets. +::: + + +```js +class CustomButton extends StatefulWidget { + final String label; + + CustomButton({required this.label}); + + @override + _CustomButtonState createState() => _CustomButtonState(); +} + +class _CustomButtonState extends State { + bool isPressed = false; + + void toggleButton() { + setState(() { + isPressed = !isPressed; + }); + } + + @override + Widget build(BuildContext context) { + return ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: isPressed + ? FlutterFlowTheme.of(context).primary // Primary color when pressed + : FlutterFlowTheme.of(context).secondaryBackground, // Default color + foregroundColor: FlutterFlowTheme.of(context).secondaryText, // Text color + ), + onPressed: toggleButton, + child: Text( + widget.label, + style: FlutterFlowTheme.of(context).bodyText1, // Themed text style + ), + ); + } +} +``` +:::info +Find the list of colors, + +### Manipulating AppState from Custom Code + +In FlutterFlow, you can access or update AppState directly from the Action Flow Editor. However, certain scenarios may require you to access or modify AppState within custom code for more control over the operation flow. The FFAppState class also provides additional helper functions to manipulate AppState variables. Let’s look at some examples: + +:::tip[Imports] +Ensure you import `import '../../flutter_flow/flutter_flow_util.dart';` when accessing `FFAppState` in custom code resources. +::: + +- **Accessing AppState in Custom Code** + +```js + +Future getCartItems() async { + // Retrieve the current cart items from AppState + final currentCartItems = FFAppState().cartItems; + print('Current Cart Items: $currentCartItems'); +} +``` + +- **Updating AppState Values in Custom Code** + +```js +Future enableDarkMode() async { + // Enable dark mode in AppState + FFAppState().update(() { + FFAppState().enableDarkMode = true; + }); + print('Dark mode enabled'); +} +``` + +- **Modifying a List in AppState Using Helper Functions** + +The `FFAppState` class offers a variety of helper functions to easily manage list variables in AppState. For a detailed overview of this generated class, check out **[this guide](../../generated-code/ff-app-state.md#managing-appstatelist)**. Here are some examples of how to use these helper functions to modify an AppState list variable: + +```js +Future addLocation(LatLng value) async { + // Add a new location to the LatLng list + FFAppState().addToLatLngList(value); +} + +Future removeLocation(LatLng value) async { + // Remove a specific location from the LatLng list + FFAppState().removeFromLatLngList(value); +} + +Future removeLocationAtIndex(int index) async { + // Remove a location at a specific index from the LatLng list + FFAppState().removeAtIndexFromLatLngList(index); +} + +Future updateLocationAtIndex(int index, LatLng Function(LatLng) updateFn) async { + // Update a location at a specific index in the LatLng list + FFAppState().updateLatLngListAtIndex(index, updateFn); +} + +Future insertLocationAtIndex(int index, LatLng value) async { + // Insert a new location at a specific index in the LatLng list + FFAppState().insertAtIndexInLatLngList(index, value); +} +``` + + +### Leverage Custom Data Types +When you create a custom data type in FlutterFlow, it **[generates a corresponding `Struct` class](../../generated-code/custom-data-type-gen.md)**. In FlutterFlow's custom code, you can create new instances of such data types, pass instances back into an action, or manipulate and retrieve information from existing objects. Here are some examples to help illustrate working with an example `ProductStruct` class. + +#### Example 1: Creating a new Instance of `ProductStruct` +To create a new `ProductStruct` instance, initialize it with the required properties: + +```js +// Create a new instance of ProductStruct +final newProduct = ProductStruct( + productId: '123', + name: 'Example Product', + description: 'A sample product description.', + category: 'Electronics', + subCategory: 'Mobile Phones', + price: PriceStruct(amount: 299.99, currency: 'USD'), + sizes: ['Small', 'Medium', 'Large'], + colors: [ColorsStruct(colorName: 'Red', colorHex: '#FF0000')], + images: [ImagesStruct(thumbnail: 'https://example.com/image.jpg')], + stockStatus: StockStatusStruct(xs: 0, small: 2), + reviews: [ReviewsStruct(rating: 4, comment: 'Great product!')], +); + +``` + +#### Example 2: Accessing Properties of an Existing `ProductStruct` object + +If you have an existing `ProductStruct` object (e.g., retrieved from a list of products), you can access its properties or return specific values back to the calling Action. + +Let's assume you have an Action that calls a Custom Action to retrieve a field value from the provided `ProductStruct` object. + +- **Returning a Single Field from ProductStruct** + +This function retrieves and returns the product's name. The return type is `String?` to account for the possibility of a null value. +```js +// Function to return the product name from a ProductStruct instance +String? getProductName(ProductStruct product) { + // Access and return the product name + return product.name; +} +``` + +- **Checking if a Field Exists in a `ProductStruct` Object** +This function determines whether the `ProductStruct` object contains a non-null value for a specific field, such as `description`. It returns `true` if the field exists and is not null, and `false` otherwise. + +```js +// Function to check if the description field exists in a ProductStruct instance +bool hasDescription(ProductStruct product) { + // Return true if the description is not null, false otherwise + return product.description != null; +} +``` + +- **Returning a List of Review Comments from ProductStruct** + +This function retrieves a list of review comments from the reviews field in the `ProductStruct`. The return type is `List` as it returns a list of comments (or an empty list if there are no reviews). + +```js +// Function to return a list of review comments from a ProductStruct instance +List getProductReviewComments(ProductStruct product) { + // Check if reviews are present and return a list of review comments + return product.reviews?.map((review) => review.comment ?? '').toList() ?? []; +} +``` + +#### Example 3: Modifying Properties of an Existing `ProductStruct` Object +You can also modify the properties of an existing `ProductStruct` object. This can be helpful if you want to update a field before saving the data back to Firebase or passing it into an action. + +- **Simple Property Modification** +In this example, we’ll modify a single property, like `productName`, of an existing `ProductStruct` object. This example is straightforward and demonstrates how to update a basic field in the object. + +```js +// Function to update the product name of a ProductStruct instance +Future updateProductName(ProductStruct product, String newProductName) { + // Update the product name with the new value + product.productName = newProductName; +} +``` + +- **Complex Property Modification - Nested Object Update** +In this more complex example, we’ll modify a nested property within the `ProductStruct`, such as updating the price (which itself is a `PriceStruct` object). This shows how to update a property that itself contains multiple fields. + +```js +// Function to update the price of a ProductStruct instance +Future updateProductPrice(ProductStruct product, double newAmount, String currency) { +// Check if price is not null + if (product.price != null) { + // Update only the amount field + product.price!.amount = newAmount; + } else { + // If price is null, optionally initialize it if needed + product.price = PriceStruct( + amount: newAmount, + currency: currency, + ); + } +} +``` + +- **Complex Property Modification - Updating a List Property** +In this example, we’ll add new items to a list property, like adding new review comments to the `reviews` list in `ProductStruct`. This example shows how to work with a list of nested objects. + +```js +Future addNewReviews(ProductStruct product) { + product.reviews ??= []; // Initialize the reviews list if it's null + product.reviews!.addAll([ + ReviewStruct(rating: 5, comment: 'Excellent product!'), + ReviewStruct(rating: 4, comment: 'Good quality, but a bit expensive.'), + ReviewStruct(rating: 3, comment: 'Satisfactory, meets expectations.'), + ]); +} +``` + +or if the new list of reviews is being provided to the Custom Action, then: + +```js +Future addDynamicReviews(ProductStruct product, List newReviews) { + product.reviews ??= []; // Initialize the reviews list if it's null + product.reviews!.addAll(newReviews); // Add the new reviews +} + +``` + + +### Using Firebase Auth Variables in Custom Code + +When using Firebase Authentication for your app, FlutterFlow provides access to key authentication data, such as `currentUserDisplayName`, `currentUserUid`, and more. These variables can be used in your Custom Actions to build additional features that require such common data from authenticated users. + +For example, you can check if a user’s email is verified before proceeding with certain actions: + +```js +if (currentUserEmailVerified) { + // Perform action for verified users +} +``` + +Or, if you need to create a directory path that includes the user’s unique ID: +```js +String directoryPath = '/users/' + currentUserUid + '/files'; +``` + +Here’s a list of other Firebase Auth variables that can be referenced in Custom Code: + +- `currentUserEmail` – The email address of the current user. +- `currentUserUid` – The unique ID of the current user. +- `currentUserDisplayName` – The display name set by the user. +- `currentUserPhoto` – The profile photo URL of the current user. +- `currentPhoneNumber` – The user’s phone number, if available. +- `currentJwtToken` – The current user’s JWT token for secure requests. +- `currentUserEmailVerified` – Boolean indicating if the user’s email is verified. + +- These variables make it easy to integrate Firebase Auth data into custom functionality, enhancing the user experience. + diff --git a/docs/ff-concepts/adding-customization/custom-actions.md b/docs/ff-concepts/adding-customization/custom-actions.md index e2d7d442..ff5d0117 100644 --- a/docs/ff-concepts/adding-customization/custom-actions.md +++ b/docs/ff-concepts/adding-customization/custom-actions.md @@ -123,7 +123,7 @@ Flow. To learn more about Custom Action settings, such as the [**Exclude From Compilation toggle**](custom-code.md#exclude-from-compilation), [**Include Build Context toggle**](custom-code.md#include-buildcontext), -and other properties like [**Callback Actions**](custom-code.md#add-a-callback-action), +and other properties like [**Callback Actions**](custom-code.md#callback-action-as-parameter), [**Pubspec Dependencies**](custom-code.md#adding-a-pubspec-dependency), please check out this [**comprehensive guide**](custom-code.md). ::: diff --git a/docs/ff-concepts/adding-customization/custom-code.md b/docs/ff-concepts/adding-customization/custom-code.md index ec36a1bc..938ca55a 100644 --- a/docs/ff-concepts/adding-customization/custom-code.md +++ b/docs/ff-concepts/adding-customization/custom-code.md @@ -17,8 +17,9 @@ This is where writing custom code comes into play. There are a few different ways to make custom code accessible in FlutterFLow: * **[Custom Functions](custom-functions.md):** Custom Dart functions that can be used to set Widget or Action properties. -* **[Custom Actions](custom-actions.md):** Custom Dart functions that can be triggered by [Action Triggers](https://docs.flutterflow.io/resources/functions/action-triggers/) or used as nodes in an [Action Flow](https://docs.flutterflow.io/resources/functions/action-flow-editor#action-flow-editor). These are usually `async` functions and are able to import custom package dependencies. -* **[Custom Widgets](custom-widgets.md):** Custom Flutter widgets, which can be used in the same way [Components](https://docs.flutterflow.io/resources/ui/components) are used throughout your project. +* **[Custom Actions](custom-actions.md):** Custom Dart functions that can be triggered by [Action Triggers](https://docs.flutterflow.io/resources/functions/action-triggers/) or used as nodes in an [Action Flow](https://docs.flutterflow.io/resources/functions/action-flow-editor#action-flow-editor). These are usually `async` functions and are able to import [custom package dependencies](#adding-a-pubspec-dependency). +* **[Custom Widgets](custom-widgets.md):** Custom Flutter widgets that can also import [custom package dependencies](#adding-a-pubspec-dependency) and be used in the same way as [Components](https://docs.flutterflow.io/resources/ui/components) throughout your project. +* **[Custom Files](custom-files.md):** Within Custom Files, you'll have the ability to edit some parts of the `main.dart` file. :::tip[Why Write Custom Code?] @@ -48,12 +49,6 @@ Note that the desktop version of the In-App Code Editor is limited. We recommend or the **[VSCode Extension](vscode-extension.md)**. ::: - -Beyond the custom code resoureces outlined above, you'll also see an additional section in the left -hand sidebar of the Custom Code page - [Custom Files:](custom-files.md). - -Within Custom Files you'll have the ability to edit some parts of the `main.dart` file. - ### Code Copilot Code Copilot is an AI-assisted feature that helps you generate code snippets, @@ -122,7 +117,7 @@ When there is a compilation error, the code analyzer will stop running and displ by the compiler. Once fixed, save the code and rerun using the Compile Code button. The code analyzer should then be reconnected. You can also manually reconnect it if needed. -### Custom Code Automatic Imports +### Automatic FlutterFlow Imports When creating a new custom code snippet (Actions, Widgets, or Functions) in FlutterFlow, some fundamental imports will be automatically added for you. These imports cannot be modified by the developer. Custom Functions do not allow adding any custom imports, but you can add custom imports in Custom Actions and Widgets after the line **"Do not remove or modify the code above"**. @@ -130,9 +125,15 @@ When creating a new custom code snippet (Actions, Widgets, or Functions) in Flut ### Custom Code Settings -When you edit a custom code snippet in FlutterFlow, the Settings block will open on the right. This -block may vary slightly depending on the type of custom code (Actions, Functions, Widgets), but here -we'll discuss the common settings. +When you edit a custom code snippet in FlutterFlow, the Settings menu opens on the right. This menu may vary slightly depending on the type of custom code (Actions, Functions, or Widgets), but here, we’ll cover the common settings. + +#### Generate Boilerplate Code +This setting allows you to generate boilerplate code, providing a structured starting point with essential code imports and a basic widget or function structure. + +![copy-boilerplate-code.png](imgs/copy-boilerplate-code.png) + +After creating a new resource file, click the code icon on the Widget Settings menu to generate the boilerplate code. Then, click "Copy to Editor" to add the boilerplate to your resource file’s code editor, where you can further customize it. + #### Exclude From Compilation @@ -156,7 +157,7 @@ context-specific data. This option is only available for Custom Actions. ::: -#### Input Arguments +## Input Arguments When writing custom code in FlutterFlow, you can define input arguments to make your custom functions, widgets, or actions more dynamic and reusable. Input arguments allow you to pass data @@ -174,7 +175,7 @@ as `Struct`. For example, if your custom data type is called `Item referenced in the generated code as `ItemsStruct`. ::: -##### Add a Callback Action +### Callback Action As Parameter A callback action is an action passed as a parameter to a custom action or widget and triggered at some point in the future when a specific event occurs. @@ -190,7 +191,7 @@ action with an Action Parameter `searchKeyword`. This means that the custom acti ![explain-callback-action.png](imgs/explain-callback-action.png) -##### Provide an Action to Callback Action +### Add an Action to Callback Action To provide a callback action to your main custom action, check out this quick guide where we provide a "**Show Snackbar**" action to `onError`, displaying a combined text using the search keyword. @@ -221,7 +222,7 @@ To provide a callback action to your main custom action, check out this quick gu -#### Return Values +## Return Values In FlutterFlow, custom code can not only take input arguments but also return values, back to the caller. Return values allow your custom functions, or actions to pass data back to the @@ -237,12 +238,14 @@ Here's an example of an Action that returns a _nullable_ integer. ![return-value-actions.png](imgs/return-value-actions.png) ## Adding a Pubspec Dependency +To utilize community-built Flutter solutions in your FlutterFlow projects, you can add a "pubspec dependency". The **pubspec file** is the configuration file in Flutter projects that lists external packages or libraries, along with other project configurations. + :::tip[Scope] -You can only add a pubspec dependency to [**Custom Action**](custom-actions.md) & [**Custom Widgets**](custom-widgets.md). +You can only add a pubspec dependency to [**Custom Actions**](custom-actions.md) & [**Custom Widgets**](custom-widgets.md). ::: -### Pub.dev +#### Pub.dev [Pub.dev](https://pub.dev) is the official package repository for Dart and Flutter. It hosts a wide range of packages, libraries, and tools that developers can use to extend the functionality of their Dart and Flutter applications. :::info[Flutter Favorite Packages] @@ -253,6 +256,18 @@ You can explore the Flutter Favorite packages on **[pub.dev's Flutter Favorites ::: +To add a pubspec dependency from [**pub.dev**](#pubdev), follow these steps: + +1. Create a new Custom Widget or Custom Action resource file, and be sure to give it a meaningful name. + +2. [**Generate the boilerplate code**](#generate-boilerplate-code) and copy the basic widget or function structure into the code editor. + +3. Select the [**package you want from pub.dev**](#choosing-the-correct-package-from-pubdev) and review its details. + +4. Copy the package name and version, and add them to the Custom Code settings in FlutterFlow. Then, copy the import statement and add it to the list of imports in the Custom Code resource. You can also copy example code from the Example tab on the package’s pub.dev page and modify it as needed — see more in the **[Setup Code](#setup-code)** section. + +5. Click "Save & **[Compile Code](#compile-code)**" to apply the changes. + ### Choosing the correct package from pub.dev You will find varieties of dependencies for a specific requirement, and choosing the best one can be @@ -280,40 +295,47 @@ one. ![Dependency-score.png](imgs/Dependency-score.png) -When adding a pubspec dependency to your custom code in FlutterFlow, you’ll need two pieces of information: the [package name with its version number](#copy-package-name--version) and the [import statement](#copying-import-statement). +When adding a pubspec dependency to your custom code in FlutterFlow, you’ll need two pieces of [information](#setup-code): the Package name with its Version number and the Import statement. -#### Copy Package Name & Version +### Setup Code +To configure your custom code with the package, copy and paste the following items from the package's pub.dev page: -To use the dependency code in our code editor, copy its name with the version. To do so, click -the **Copy to Clipboard** icon. +1. **Copy Package Name & Version** -

+To use the dependency in your Custom Action or Custom Widget resource file, go to the package's pub.dev page and click the **Copy to Clipboard** icon next to the package name and version. Then, paste it into the **Pubspec Dependency** section (bottom right) of the FlutterFlow code editor. + +![package-dependency-version-copy.png](imgs/package-dependency-version-copy.png) + + +See **[example](#add-pubspec-dependency-to-custom-code-example-guide)** for more information. -![img.png](imgs/img.png) -

:::warning The current dependency might depend on other dependencies to work. So make sure you also copy the -name and version of all the additional dependencies to specify in the code editor. -::: +name and version of all the additional dependencies to specify in the code You can check if the current dependency has any additional dependencies inside the '*Dependencies'* section at the bottom right side. + ![img_1.png](imgs/img_1.png) +::: -#### Copying import statement +2. **Copying Import Statement** -An import statement points to where the dependency's code is located. When making a custom widget or -action, place this statement at the beginning of the code editor. +An import statement specifies the location of the dependency's code. When creating a custom widget or action, add this statement at the end of the default import statements in the code editor. -Open the dependency page and select the installing tab; under the Import it section, you'll find +Open the dependency page and select the **Installing** tab; under the **Import It** section, you'll find the import statement. To copy, click the **Copy to Clipboard** icon. -![img_2.png](imgs/img_2.png) +![copy-import-statement.png](imgs/copy-import-statement.png) + +3. **Copy Example Code** + +Example code is always available in the **Example** tab on the package’s pub.dev page. Copy any relevant snippets that demonstrate usage, and paste them into your custom widget or function file. You can then modify the code as needed to fit your project. -### Add Pubspec Dependency to Custom Code: Guide +## Add Pubspec Dependency to Custom Code: Example Guide In this example, we are using the [**flutter_rating_bar**](https://pub.dev/packages/flutter_rating_bar) dependency to create a `ProductRatingBar` custom widget for our @@ -349,7 +371,7 @@ FlutterFlow:

:::note -This example demonstrates how to add a [pub.dev](https://pub.dev) package to a Custom Widget snippet, but you can follow the same process for adding a package to Custom Actions. For a deep dive, explore the detailed documentation on **[Custom Widgets](custom-widgets.md)** and [Custom Actions](custom-actions.md). +This example demonstrates how to add a [**pub.dev**](https://pub.dev) package to a Custom Widget snippet, but you can follow the same process for adding a package to Custom Actions. For a deep dive, explore the detailed documentation on **[Custom Widgets](custom-widgets.md)** and [**Custom Actions**](custom-actions.md). ::: diff --git a/docs/ff-concepts/adding-customization/custom-functions.md b/docs/ff-concepts/adding-customization/custom-functions.md index f02ec7a2..5060ea06 100644 --- a/docs/ff-concepts/adding-customization/custom-functions.md +++ b/docs/ff-concepts/adding-customization/custom-functions.md @@ -3,7 +3,7 @@ slug: /concepts/custom-code/custom-functions title: Custom Functions description: Learn how to create and use custom functions in your FlutterFlow app to add custom functionalities. tags: [Custom Functions, Custom Code] -sidebar_position: 3 +sidebar_position: 2 keywords: [FlutterFlow, Custom Functions, Customizations, Flutter, Dart, Pub.dev] --- diff --git a/docs/ff-concepts/adding-customization/custom-widgets.md b/docs/ff-concepts/adding-customization/custom-widgets.md index f77101a5..7f4ddbec 100644 --- a/docs/ff-concepts/adding-customization/custom-widgets.md +++ b/docs/ff-concepts/adding-customization/custom-widgets.md @@ -3,7 +3,7 @@ slug: /concepts/custom-code/custom-widgets title: Custom Widgets description: Learn how to create and use custom widgets in your FlutterFlow app to enhance its user interface. tags: [Custom Widgets, Custom Code] -sidebar_position: 5 +sidebar_position: 2 keywords: [FlutterFlow, Custom Widgets, Customizations, Flutter, Dart, Pub.dev] --- @@ -174,7 +174,7 @@ FlutterFlow also allows you to view your custom widget once it is successfully c :::tip[LOOKING for other CUSTOM action properties?] To learn more about Custom Widget settings, such as the [**Exclude From Compilation toggle**](custom-code.md#exclude-from-compilation), -and other properties like [**Callback Actions**](custom-code.md#add-a-callback-action), +and other properties like [**Callback Actions**](custom-code.md#callback-action-as-parameter), [**Pub Dependencies**](custom-code.md#adding-a-pubspec-dependency), please check out this [**comprehensive guide**](custom-code.md). ::: diff --git a/docs/ff-concepts/adding-customization/imgs/copy-boilerplate-code.png b/docs/ff-concepts/adding-customization/imgs/copy-boilerplate-code.png new file mode 100644 index 00000000..824ed8a2 Binary files /dev/null and b/docs/ff-concepts/adding-customization/imgs/copy-boilerplate-code.png differ diff --git a/docs/ff-concepts/adding-customization/imgs/copy-import-statement.png b/docs/ff-concepts/adding-customization/imgs/copy-import-statement.png new file mode 100644 index 00000000..dfe2b2ad Binary files /dev/null and b/docs/ff-concepts/adding-customization/imgs/copy-import-statement.png differ diff --git a/docs/ff-concepts/adding-customization/imgs/img.png b/docs/ff-concepts/adding-customization/imgs/img.png deleted file mode 100644 index ecc1536b..00000000 Binary files a/docs/ff-concepts/adding-customization/imgs/img.png and /dev/null differ diff --git a/docs/ff-concepts/adding-customization/imgs/package-dependency-version-copy.png b/docs/ff-concepts/adding-customization/imgs/package-dependency-version-copy.png new file mode 100644 index 00000000..fd8f50cb Binary files /dev/null and b/docs/ff-concepts/adding-customization/imgs/package-dependency-version-copy.png differ diff --git a/docs/ff-concepts/adding-customization/imgs/return-widget-custom-code.png b/docs/ff-concepts/adding-customization/imgs/return-widget-custom-code.png new file mode 100644 index 00000000..2b686df4 Binary files /dev/null and b/docs/ff-concepts/adding-customization/imgs/return-widget-custom-code.png differ diff --git a/docs/ff-concepts/adding-customization/imgs/suggestions-dropdown.png b/docs/ff-concepts/adding-customization/imgs/suggestions-dropdown.png new file mode 100644 index 00000000..bf30a9df Binary files /dev/null and b/docs/ff-concepts/adding-customization/imgs/suggestions-dropdown.png differ diff --git a/docs/generated-code/custom-data-type-gen.md b/docs/generated-code/custom-data-type-gen.md new file mode 100644 index 00000000..445f5482 --- /dev/null +++ b/docs/generated-code/custom-data-type-gen.md @@ -0,0 +1,16 @@ +--- +title: Custom Data Types +slug: /generated-code/custom-data-types +sidebar_position: 2 +--- + +# DataTypeStruct class + +:::info[Prerequisites] +This guide uses example of the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v1)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**. +::: + + +When you create a custom data type in the FlutterFlow editor, a corresponding class is generated in the code to act as a structured container for your data, similar to a `Struct`. This class includes simple getters and setters for each field. For example, if your data type in FlutterFlow is named "Product", the generated class will be named `ProductStruct` and can be found in the `product_struct.dart` file. + +![custom-data-type-gen-class.png](imgs/custom-data-type-gen-class.png) \ No newline at end of file diff --git a/docs/generated-code/ff-app-state.md b/docs/generated-code/ff-app-state.md index 5ac9ce1d..a54c8137 100644 --- a/docs/generated-code/ff-app-state.md +++ b/docs/generated-code/ff-app-state.md @@ -1,5 +1,6 @@ --- title: FFAppState +sidebar_position: 2 --- # FFAppState @@ -47,8 +48,8 @@ class FFAppState extends ChangeNotifier { The `_enableDarkMode` is an App State variable created by developer that creates its own corresponding getter and setter. -## Updating FFAppState -When updating the FFAppState from the Action Flow Editor, you will be presented with several **[update type](../resources/data-representation/app-state.md#update-type)** options such as **Rebuild All Pages**, **Rebuild Current Page**, and **No Rebuild**. Let's see how the generated code changes when these options are selected. +## Rebuild on Updating AppState +When updating an `AppState` variable from the Action Flow Editor, you will be presented with several **[update type](../resources/data-representation/app-state.md#update-type)** options such as **Rebuild All Pages**, **Rebuild Current Page**, and **No Rebuild** in the Action Settings. Let's see how the generated code changes when these options are selected. ### Rebuild Current Page When a developer chooses to update App State with the update type set to **Rebuild Current Page**, the corresponding `setter` is called. Immediately after, `setState((){});` is invoked, which updates only the current page. diff --git a/docs/generated-code/imgs/custom-data-type-gen-class.png b/docs/generated-code/imgs/custom-data-type-gen-class.png new file mode 100644 index 00000000..c6954638 Binary files /dev/null and b/docs/generated-code/imgs/custom-data-type-gen-class.png differ diff --git a/docs/generated-code/page-model.md b/docs/generated-code/page-model.md index 8f0009ac..9983cb48 100644 --- a/docs/generated-code/page-model.md +++ b/docs/generated-code/page-model.md @@ -1,7 +1,8 @@ --- title: PageModel class +sidebar_position: 4 --- -# PageModel Class +# PageModel class :::info[Prerequisites] This guide uses example of the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v1)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**. diff --git a/docs/resources/data-representation/custom-data-types.md b/docs/resources/data-representation/custom-data-types.md index 62c0a6c5..1aa647cb 100644 --- a/docs/resources/data-representation/custom-data-types.md +++ b/docs/resources/data-representation/custom-data-types.md @@ -24,7 +24,7 @@ Custom data types have several key advantages: - Use custom data type when predefined data types, such as _integer_ and _string_ may not be enough to store certain kinds of information. - FlutterFlow also supports some [**Built-in Data Types**](data-types.md#built-in-data-types). ::: -![custom-data-types.avif](..%2Fimgs%2Fcustom-data-types.avif) +![custom-data-types.avif](../imgs/custom-data-types.avif) When you create a custom data type, it internally creates a Struct. A struct, or structure, is a composite data type that lets you combine fields of different data types to construct a data structure to suit your specific needs.