Style

Style

The Style Module aims to address common challenges in Flutter app development, such as maintaining a consistent visual style across the application, handling theme variations, and applying styles to individual widgets. By providing a centralized styling system, the Style Module enables developers to focus on building the app's functionality while ensuring a polished and cohesive user interface.

Emphasis

The Style Module introduces the concept of "emphasis", which allows you to control the visual prominence of components within your application. Emphasis is divided into three levels: subtle, regular, and strong. By applying the appropriate emphasis level to a component, you can guide the user's attention and create a clear visual hierarchy.

For example:

StyledButton.subtle(...) // Renders a button that should not draw much attention.
StyledButton(...) // Renders a button with the default emphasis.
StyledButton.strong(...) // Renders a button with high prominence.

Color Palette

The ColorPalette functionality enables dynamic color selection based on the background color and emphasis level. It simplifies the process of choosing contrasting colors for text and other elements against different backgrounds, ensuring readability and visual harmony.

final colorPalette = context.colorPalette();
final textColor = colorPalette.foreground.regular; // Use foreground.strong for an emphasized text, or foreground.subtle for subtle text.
final buttonBackgroundColor = colorPalette.background.regular; // Use background.strong or background.subtle to define emphasis.
final buttonTextColor = buttonBackgroundColor.foreground.regular; // [buttonBackgroundColor] is both a `Color` and a `ColorPalette`, so you can see what the text's foreground color should be.

With the ColorPalette, you can use a set of colors that automatically adapt to the background color of a widget. This means that text and other elements will always be legible and visually appealing, regardless of the background they are placed on. The emphasis level allows you to further fine-tune the color selection based on the desired prominence of an element.

Using Pre-built StyleComponents will automatically update the ColorPalette in the widget tree so that children widgets have an appropriate understanding of parent's background color.

Existing Styles

Flood provides two built-in styles: DeltaStyle and FlatStyle. These styles offer a solid foundation for creating visually appealing and consistent user interfaces. To demonstrate, a screenshot of a Todo app is pasted alongside each style.

DeltaStyle

DeltaStyle is a modern and sleek style inspired by this Figma board (opens in a new tab). It supports both light and dark themes well.

final style = DeltaStyle(
  primaryColor: Color(0xff9333ea),
  backgroundColor: Color(0xff181A20),
);

Delta Style Dark Delta Style Light

FlatStyle

FlatStyle is a versatile and lightweight style that emphasizes simplicity and efficiency. You can see an example of it in action in Valet (opens in a new tab). It only supports dark themes for now.

final style = FlatStyle(
  primaryColor: Color(0xff9333ea),
  backgroundColor: Color(0xff181A20),
);

Flat Style Dark

Both DeltaStyle and FlatStyle serve as excellent starting points for creating beautiful and functional user interfaces. You can choose the style that aligns with your design vision and customize it further to match your specific requirements.

StyleComponents

The building-blocks the Style Module are Styles, which render StyleComponents. A StyleComponent is a Widget that doesn't render itself, but relies on the current Style passed through the Widget tree to render it. There are many pre-built StyleComponents with implementations already created and ready for use.

Pre-Built StyleComponents

The Style Module includes a variety of pre-built StyleComponents:

  • StyledText: Streamlines text styling by offering a concise syntax for applying attributes such as bold, strong emphasis, alignment, and style, reducing verbosity and enhancing code readability.
  • StyledList: Simplifies the creation of lists by allowing the composition of attributes for columns and rows. It provides a concise way to define the appearance and behavior of list elements.
  • StyledContainer: Serves as a base container that accepts an optional emphasis and can be fully customized. It passes a new ColorPalette to its children, ensuring they are styled correctly based on the container's emphasis.
  • StyledCard: An opinionated card component that supports emphasis and consists of a header, body, leading, trailing, children, and actions. It is designed to display a piece of content in a visually appealing and structured manner.
  • StyledButton: A button component that can be emphasized and contains a label, icon, and an onPressed callback. It intelligently handles the loading state when the onPressed callback returns a Future, preventing multiple presses and displaying a loading indicator while the action is being processed.
  • Input Fields: A collection of form field components, including StyledTextField, StyledCheckbox, StyledDateTimePicker, StyledOptionField, and StyledRadioField. These fields support emphasis and are used to capture user input effectively.
  • StyledPage: A component for creating structured and customizable pages with a title, actions, and body. Supports regular and refreshable variants, enhancing the user experience.
  • StyledMessage: A message component that can be displayed at the bottom of the page using context.showMessage(). It functions as a toast, providing informative or feedback messages to the user.
  • StyledDialog: A dialog component that appears from the bottom of the page, offering confirmation functionality through StyledDialog.yesNo(). It can also contain a custom body with any desired widgets, allowing for flexible dialog content.

There are more that aren't documented here as well. For those with access to Flood's source code, feel free to explore the style package to see the other pre-built components.

To learn more about how to use the pre-built StyleComponents in your UIs, refer to the presentation layer of the Example Todo (opens in a new tab) app.

Customization

You can define your own StyleComponent by simply extending StyleComponent, and adding StyleComponentRenderers to your Style to render them. Here's an example:

example/lib/widgets/styled_header.dart
class StyledHeader extends StyleComponent {
  final String? text;
 
  StyledHeader(this.text);
}
example/lib/widgets/styled_header_renderer.dart
class MyCustomStyleHeaderRenderer with IsTypedStyleRenderer<StyledHeader> {
  @override
  Widget renderTyped(BuildContext context, StyledHeader component) {
    return StyledText.xl(component.text);
  }
}
example/lib/style.dart
final style = FlatStyle()
    ..addRenderer(MyCustomStyleHeaderRenderer());

Instead of creating StyleComponents for every new component in your app, it's recommended to just create a Widget that composes multiple pre-built StyleComponents together. StyleComponents should only represent the building-blocks of a Style, and more complex widgets should just use the existing StyleComponents.

Styleguide

The Style Module includes a powerful tool called the Styleguide that allows you to preview and test the appearance of different components in your application. The Styleguide provides a visual reference for designers and developers, ensuring consistency and adherence to the defined style.

To access the Styleguide, you can navigate to /_styleguide in your app. Check out the Url Bar Module to see how to navigate to that page within a mobile device.

Styleguide

Use with Pond

While you don't need to use the Style Module with Pond, it's recommended as Pond will automatically take care of setting the top-most Provider necessary for your widgets to locate what the current Style is.

Simply pass in the Style into the FloodAppComponent.

example/lib/main.dart
await appPondContext.register(FloodAppComponent(style: style));