DEV Community

Cover image for Mint 🍃: Components
Szikszai Gusztáv
Szikszai Gusztáv

Posted on • Edited on

Mint 🍃: Components

In the previous post I showed you how to get started with Mint. In this post I will show you how to use Components :)

Components are the main building blocks of an application because they provide composition, can have their own state, their own styles, connect to a Store to use some global state and more...

If you are familiar with class components in React this will feel familiar.

Defining a Component

The minimal definition of a Component looks like this:

component MyComponent {
  fun render : Html {
    <div>
      "Hello World"
    </div>
  }
}
Enter fullscreen mode Exit fullscreen mode

The component keyword is used to define a component (the name must start with an uppercase letter).

In the body of the component a render function must be defined (you will get a nice compiler error if it is not there) which must return HTML or a string or an array of either (the type should match one of Html, String, Array(Html) or Array(String))

You might notice there is no return keyword, in Mint everything is an expression like the body of a function which is returned implicitly.

Composition

Now that we have our component we want to use it so we will add it to the Main component (it is the component which gets rendered by the application, you can think of it as the root component).

component Main {
  fun render : Html {
    <MyComponent/>
  }
}
Enter fullscreen mode Exit fullscreen mode

As you can see it's similar to an HTML tag but instead of an lowercase tag, the name of the component is used.

Since Main is a component, this shows that components can be composed in each other, even recursively.

As you can see the component is self closing which means it does not have a closing tag, it can have a closing tag but it's not necessary if it does not have children.

Properties

Just like HTML tags, components can have properties (or attributes if you like that word better).

Properties can be defined in the body of a component with the property keyword:

component MyComponent {
  property target : String = "Word"

  fun render : Html {
   <div>
     "Hello "
     <{ target }>
   </div>
  }
}
Enter fullscreen mode Exit fullscreen mode

Properties must have a type and a default value it is so for the compiler can help you when they are used.

You can reference a property inside the component with it's name, like in the HTML expression inside the div (<{ ... }> is an HTML expression).

You can pass values to the component from it's parent like you would do with an HTML attribute (strings can be the same, other values use brackets)

component Main {
  fun render : Html {
    <div>
      <MyComponent target="Joe"/>
      <MyComponent target={"Bill"}/>
    </div>
  }
}
Enter fullscreen mode Exit fullscreen mode

Styles

A component can have it's own scoped styles which are written using CSS and can be attached to HTML tags:

component MyComponent {
  property target : String = "Word"

  style target {
   font-style: italic;
   font-weight: bold;
  }

  fun render : Html {
   <div>
     "Hello "
     <span::target>
       <{ target }>
     </span>
   </div>
  }
}
Enter fullscreen mode Exit fullscreen mode

A style is defined by the style keyword and it's identifier. The identifier can be used to attach the styles to an element using the :: symbol.

In the example above we attached the style named target to the span which contains the target property.

That's it for this post, thank you for reading 🙏


If you like to learn more about Mint check out the guide 📖

In the next part I'm going to show how to handle events and state inside of a component 😉 see you there 👋

Top comments (4)

Collapse
 
jleblanc profile image
Josh LeBlanc

I'd love a guide on connecting to an api. That's a pretty crucial part of a SPA that isn't really touched on in the docs.

It seems to me that might be done in a provider, but it could just be done manually in a store, too.

Collapse
 
gdotdesign profile image
Szikszai Gusztáv
Collapse
 
jleblanc profile image
Josh LeBlanc

Excellent!

Collapse
 
gdotdesign profile image
Szikszai Gusztáv

Thanks for the suggestion :) I already have the subject of the next post which is events and state, but after that I'll do one about HTTP requests, so keep an eye out :D