Join our Discord server for community support and discussions Icon description

From Figma to Visual Studio – Adding Back-End Logic to Goodreads App

Now that we have three working views from our previous articles (Part 1, Part 2, Part 3), we can consume them in an Uno Platform App right from Visual Studio. 

The Uno Platform Figma plugin has two tabs of interest, the XAML tab, and the Themes tab. The XAML tab houses the generated code for the page you created in Figma, while the Themes tab houses the Resource Dictionary for the page you created.

The sample app created can be broken down into four parts:

a. Models
b. View models and seeded Data
c. Views
d. Resource Dictionaries

To Follow along, ensure you have set up your environment for Uno Platform. If you are new to Uno Platform, following our official getting started guide is the best way to get started.

Models

I created 2 Model classes for this recreation effort: The Author and Book. The Author class represents an Author Object which can be linked to a Book object since a Book has an Author property. In addition, I used an Enum to encapsulate several properties in the Book and Author classes, such as the types of Genres a book can fall under. The code snippets below show the two models and Enums created.

				
					public class Author
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public Rating AverageRatings { get; set; }
  public int RatingCount { get; set; }
  public Uri ImageUrl { get; set; }
}

				
			
				
					Public class Book
{
    public Guid Id { get; set; }
    public string ISBN { get; set; }
    public Uri Url { get; set; }
    public int Pages { get; set; }
    public string Publisher { get; set; }
    public DateTime Published { get; set; }
    public string Title { get; set; }
    public Author Author { get; set; }
    public string Description { get; set; }
    public Genre Genre { get; set; }
    public decimal Price { get; set; }
    public Rating AverageRating { get; set; }
    public int RatingsCount { get; set; }
    public State State { get; set; }
 }

				
			
				
					Public enum State
{
    WantToRead,
    Read,
    CurrentlyReading
}

Public enum Rating
{
    One,
    Two,
    Three,
    Four,
    Five
}

Public enum Genre
{
    Action,
    Adventure,
    Comedy,
    Drama,
    Horror,
    Mystery,
    Romance,
    SciFi,
    Thriller,
    Western,
    Fiction,
    NonFiction,
    Biography
}

				
			

View Model & Seeded Data

I installed the Bogus NuGet package to generate fake data based on the models and enums created and subsequently seed it into the app via the
Corresponding view models are attached to each page. For example, the code snippet below shows the setup for data seeding and how to consume it in a view model.

				
					public class Author
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public Rating AverageRatings { get; set; }
  public int RatingCount { get; set; }
  public Uri ImageUrl { get; set; }
}

				
			

Views

We obtained three sets of XAML-generated code from the previous articles, one for the Home page, one for the Author Profile, and the last for the Book Details. In our application on Visual Studio, I created a Navigation view on the MainPage.xaml and added three Navigation view items corresponding to the three XAML codes generated from Figma.

I created three pages and set the Navigation view items content to the three pages. Then for each page, I copied one Figma-generated XAML to replace the content section for the corresponding page, i.e., The Figma XAML code for the home page template was copied into the Homepage.xaml file, and Author Profile was copied into AuthorPage.xaml and Book Profile were copied into BookPage.xaml.

The next step was to hook up the view model with the view via data binding data from the page’s view models to the views of several constituent controls. I also created some converters to convert the Enums to an appropriate value that a utilizing control can consume.

				
					using Bogus;
using Bogus.DataSets;

using System;
using System.Collections.Generic;
using System.Text;

namespace UnoGoodReads.Models
{
    public class SeedData
    {
        Faker<Author> authorFaker = new Faker<Author>()
            .RuleFor(a => a.Id, f => Guid.NewGuid())
            .RuleFor(a => a.Name, f => f.Name.FullName())
            .RuleFor(a => a.AverageRatings, f => f.PickRandom<Rating>())
            .RuleFor(a => a.RatingsCount, f => f.Random.Number(1, 1000))
            .RuleFor(a => a.ImageUrl, f => new Uri(f.Image.PlaceImgUrl(width: 200, height: 300, category: "people")));

        Faker<Book> bookFaker = new Faker<Book>()
            .RuleFor(b => b.Id, f => Guid.NewGuid())
            .RuleFor(b => b.ISBN, f => f.Commerce.Ean13())
            .RuleFor(b => b.Url, f => new Uri(f.Image.PicsumUrl(width: 200, height: 300)))
            .RuleFor(b => b.Pages, f => f.Random.Number(1, 1000))
            .RuleFor(b => b.Publisher, f => f.Company.CompanyName())
            .RuleFor(b => b.Published, f => f.Date.Past())
            .RuleFor(b => b.Title, f => f.Lorem.Sentence(null,3))
            .RuleFor(b => b.State, f => f.PickRandom<State>())
            .RuleFor(b => b.Description, f => f.Lorem.Paragraph())
            .RuleFor(b => b.Genre, f => f.PickRandom<Genre>())
            .RuleFor(b => b.Price, f => f.Random.Number(1, 100))
            .RuleFor(b => b.AverageRating, f => f.PickRandom<Rating>())
            .RuleFor(b => b.RatingsCount, f => f.Random.Number(1, 1000));

        public List<Book> FakeBooks { get; set; }
        public List<Author> FakeAuthors { get; set; }
        public SeedData()
        {
            FakeAuthors = authorFaker.Generate(10);
            FakeBooks = bookFaker.Generate(100);

            foreach(Book book in FakeBooks)
            {
                var author = FakeAuthors[new Random().Next(FakeAuthors.Count)];
                book.Author = author;
            }
            
        }
    }
}
				
			

Resource Dictionaries

As mentioned in the first article of this series, it’s best practice to set up the colors of your App to match the overall theme at the start of the project. For example, before we began the Goodreads project, we specified color styles to match the Goodreads app theme before creating our screens in Figma. To utilize these updated color values and use your color resources, different from the default set of colors provided, you can create a ResoureDictionary, with a name such as ColorOverride.xaml, and override the default color values. You can then set the OverrideSource property of MaterialColors in your App.xaml to point to ColorOverride.xaml.”

				
					<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <XamlControlResources xmlns="using:Microsoft.UI.Xaml.Controls" />
            <ToolkitResources xmlns="using:Uno.Toolkit.UI" />
            
            <!-- Add resource dictionaries here -->
            <ResourceDictionary Source="ms-appx///Styles/MainDictionary.xaml" />
            
             <!-- Load Uno.Material Resources -->
             
             <MaterialColors xmlns="using:Uno.Material"
                             OverrideSource="ms-appx:///Styles/MainDictionary.xaml" />
            <MaterialFonts xmlns="using:Uno.Material" />
            <MaterialResources xmlns="using:Uno.Material" />
            <MaterialToolkitResources xmlns="using:Uno.Toolkit.UI.Material" />
            
            <!--Load custom application resources -->
            
        </ResourceDictionary.MergedDictionaries>
        <!-- Add resources here -->
    </ResourceDictionary>
</Application.Resources>
				
			
Explanation

Uno.Material comes with a prebuilt set of Colors—things like PrimaryColor, SecondaryColor, OnPrimaryColor, etc. By default, PrimaryColor comes out of the box with some color set to it, say it’s Purple. An application using Uno.Material whose branding’s main color is Red would create this ColorOverride.xaml file and essentially “redefine” the PrimaryColor resource. So you’d set PrimaryColor = Red, and MaterialColors will automatically generate the rest of the resources based on PrimaryColor.

So there may be a resource in Material that provides you the PrimaryColor but at an opacity of 12% or something. If you override PrimaryColor to Red, the resource will automatically be Red at 12% opacity instead of Purple at 12% opacity.

Next Steps

We built the Uno Platform for Figma plugin to help designers and developers accelerate the design-to-code handoff. By providing a tool that lets you export your Figma design assets and generate clean, responsive XAML, helping reduce up to 50% time to start projects or new app screens.

Check out our entire Goodreads series to see how you can turn your high-fidelity Figma designs into XAML code that could be built upon and extended quickly.

Thank you, Paula Aliu, for an incredible and in-depth guide showcasing how using Uno Platform Plugin, Uno Material Toolkit, and Figma in combination can help accelerate design-to-code handoff.

Share this post:

Uno Platform 5.2 LIVE Webinar – Today at 3 PM EST – Watch