Defining styles on Beagle ios

Here, you’ll find a tutorial of how to configure a Design System for Beagle on iOS.

Creating styles for Beagle iOS

On the first use example, you saw how to implement Beagle and create your first server-driven screen.

In this tutorial, the idea is to get deeper from the previous project to create a Design System on Beagle’s library. To better illustrate the explanation, we’ll use these sample codes that you can find out in our repository.

The idea is to configure some styles on iOS to allow you to customize some components, such as:

  • Text.
  • Button.
  • Navigation Bar
  • Tab View
  • Entre outros.

Besides, we’ll apply text styles to 2 texts' components.

To do so, we’ll create a kind of Design System, which is a file with a set of styles in where we’ll keep the styles' components registers created on frontend.

This way, your iOS application “will know” which style component must be rendered in a server-driven screen. Just remember that the server-driven screen case, the visual components (views) will be related and it will be used to build the screen.

Step 1: Create a Swift file

Create a Swift file. On our example, let’s call it Styles. On this file, you must import the UIKit and the BeagleUI and also create a Struct with the name Styles, just like the image below:

import UIKit
import Beagle

struct Styles {

}

This struct will contain all the styles Beagle will access. Here, it will be listed the logic that allows Beagle to apply defined styles on iOS into a server-driven screen.

Step 2: Create a text style

Once you have created your file, now you must create a static function to define and return a text style. For this example, we’ll have one style for a title and another one for the paragraph, so we’ll create two different functions.

This function return will use the BeagleStyle class, which is a Beagle’s intern class that’s available when you import the beagleUI class.

It’s on these return that’s defined the style created for the text component. Follow the instructions below to create each function:

The title text style will return Courier font with size 20 and orange color. Implement it like in the example below:

static func titleTextStyle() -> (UITextView?) -> Void {
    return BeagleStyle.text(
        font: UIFont.init(name: "Courier", size: 20) ?? UIFont.systemFont(ofSize: 20), 
        color: .orange
    )
}

Repeat the same process to create our paragraph style, like in the example below:

static func descriptionTextStyle() -> (UITextView?) -> Void {
    return BeagleStyle.text(
        font: UIFont.init(name: "Courier", size: 15) ?? UIFont.systemFont(ofSize: 15), 
        color: .orange
    )
}

After you implement both styles, your Styles file must be like this:

import UIKit
import Beagle

struct Styles {

    static func titleTextStyle() -> (UITextView?) -> Void {
        return BeagleStyle.text(
            font: UIFont.init(name: "Courier", size: 20) ?? UIFont.systemFont(ofSize: 20), 
            color: .orange
        )
    }
    
    static func descriptionTextStyle() -> (UITextView?) -> Void {
        return BeagleStyle.text(
            font: UIFont.init(name: "Courier", size: 15) ?? UIFont.systemFont(ofSize: 15), 
            color: .orange
        )
    }
}

Step 3: Register a style on Beagle Config

Now, it is necessary to register Beagle’s styles, which is important so Beagle can be able to apply these styles in server-driven screens.

  1. Open the BeagleConfig file. Register a constant called theme

  2. It’s on the theme constant where the styles will be listed.

  3. This constant will receive the AppTheme , which is where the styles are registered.

  4. Create the information block below inside the**static func config** function.

  5. Create the information block below inside the**static func config** function.

    let theme = AppTheme(styles: [])
    
    1. To register, list the style name stated on backend and, then, indicate which style must be applied. Each style must be registered like this:
"Title.Text.Orange": Styles.titleTextStyle

The theme constant with two registered styles must be like this:

let theme = AppTheme(styles: [
    "Title.Text.Orange": Styles.titleTextStyle,
    "Description.Text.Orange": Styles.descriptionTextStyle
])

Still on BeagleConfig, we should refer the theme we created on BeagleDependencies.

Follow the example below and finish the BeagleConfig’s setup as the example below shows:

import Beagle
import Foundation

class BeagleConfig {
    static func config() {
        
        let theme = AppTheme(styles: [
            "Title.Text.Orange": Styles.titleTextStyle,
            "Description.Text.Orange": Styles.descriptionTextStyle
        ])
        
        let dependencies = BeagleDependencies()
        dependencies.theme = theme
        dependencies.urlBuilder = UrlBuilder(
            baseUrl: URL(string: "http://localhost:8080")    
        )
        Beagle.dependencies = dependencies
    }
}

In this way, the frontend is configured and the styles are defined.

Step 4: Define styles on backend

On the backend’s configuration tutorial, we created a server-driven page with 2 texts: 1 title and 1 paragraph.

This page was like that when rendered on frontend:

To attribute a style to these texts, follow these instructions:

  1. Open the backend project (BFF) and look for the FirstScreenBeagleBuilderfile.
  2. This is the file that contains the code of your first server-driven screen.
  3. She must be configured like in the image below.
  4. On it, you will notice that it was built a hierarchy’s screen components and two text types components.
class FirstScreenBuilder : ScreenBuilder {
    override fun build() = Screen(
        child = Container(
            children = listOf(
                Text(
                    text = "Hello Beagle",
                    styleId = "Title.Text.Orange"
                ).applyStyle(
                    Style(
                        margin = EdgeValue(
                            top = 16.unitReal()
                        ),
                        flex = Flex(alignSelf = AlignSelf.CENTER)
                    )
                ),
                Text(
                    text = "Beagle is a cross-platform framework which provides " +
                           "usage of the Server-Driven UI concept, natively in " +
                           "iOS, Android and Web applications. By using Beagle, " +
                           "your team could easily change application's layout " +
                           "and data by just changing backend code.",
                    styleId = "Description.Text.Orange"
                ).applyStyle(
                    Style(
                        margin = EdgeValue(
                            left = 16.unitReal(),
                            right = 16.unitReal(),
                            top = 20.unitReal()
                        )
                    )
                )
            )
        )
    )

To add a style to a text element, you must list the style name within the text component, as shown below. Don’t forget to separate the components with a comma. Hold the Ctrl button and place the mouse over the Text component and will see the list of attributes that this component can receive here on the backend. For now, we will only use Style.

 1. Put a comma after the text attribute = "Hello Beagle", and write another attribute you want to define, in our case it's `styleId`

 2. Type a `“Title.Text.Orange”` string and done! Your style is defined for this text component.
Text(
    text = "Hello Beagle",
    styleId = Tille.Text.Organge
).applyFlex(
        Flex(
            margin = EdgeValue(
                top = 16.unitRal(Real)
            ),
            alignSelf = Alignment.CENTER
        )
),

And done, that’s all we’re gonna do on our backend so far.

  • Repeat the same process with the other Text component - the paragraph -, but name it as “Description.Text.Orange”

You can run your backend’s application so the service can be available.

What’s next?

After you execute the backend, you now have to execute the Xcode.

This should be your result:

Now that is ready, test a little more, try to change sizes, colors and whatever style you want to!

For this example, it was used simple style’s elements to explain Design System, but the number of functions is quite big. That means you can develop different toolBars, buttons and all kinds of components, including customized components to use on Beagle.


Last modified February 12, 2021: Fix/migrate images to aws (#299) (a7bb5457)