One of the languages/technologies I want to learn this year is Mint. Here is a first approach to the language.
Introduction
We are starting a new journey upon the lands of Single-Page Applications development. And as adventurers say:
Better start a new journey with a breath of fresh air!
wait ... what? π€
ok, well, I don't know if that's what they say π€£ but bear with me: we are starting an awesome web application development journey with the programming language Mint!
The map
An awesome journey needs an awesome map, just like J.R.R. Tolkien's Middle-earth map. In our case, these are going to be our next steps:
- What is Mint
- Installing Mint
- Building our first application:
init
start
- An initial
component
- The
store
- The full
component
- Events
- CSS
Our 10-step journey begins ... now!π
What is Mint?
As said in Mint's guide:
Mint is a language specifically created for writing single-page applications. It is a compiler and a framework combined to provide great developer experience while allowing to write safe, readable and maintainable code.
Moreover, Mint will provide us with React abstractions (components and stores) and all this protected by a type system, making writing single-page applications a fun task! Mint's output will be our application in JavaScript, ready to run in the browser.
Also, Mint itself is written in Crystal and it's open source! Yeah! π€π
Installing Mint
We are going to create an application, so let's start installing the Mint language
a few minutes later
Ok, are we all done? Let's try the mint-lang
command:
$ mint-lang --help
Usage:
mint-lang [flags...] [arg...]
Mint
Flags:
--env, -e (default: "") # Loads the given .env file
--help # Displays help for the current command.
Subcommands:
build # Builds the project for production
compile # Compiles the project into a single JavaScript
docs # Starts the documentation server
format # Formats source files
init # Initializes a new project
install # Installs dependencies
loc # Counts Lines of Code
start # Starts the development server
test # Runs the tests
version # Shows version
--help
working great! And the version
command:
$ mint-lang version
Mint - Showing version
βββββββββββββββββββββββββββββββββββββββββββββββββ
Mint 0.7.1
βββββββββββββββββββββββββββββββββββββββββββββββββ
All done in 3.362ms!
Building our first Mint application
This first application is the great-awesome-as-always Counter App
The magic word: init
Let's create the project with:
$ mint-lang init counter
Mint - Initializing a new project
βββββββββββββββββββββββββββββββββββββββββββββββββ
β Creating directory structure...
β Writing initial files...
There are no dependencies!
There is nothing to do!
βββββββββββββββββββββββββββββββββββββββββββββββββ
All done in 3.428ms!
Here's the resulting project's structure:
counter
βββ source
β βββ Main.mint
βββ tests
β βββ Main.mint
βββ .gitignore
βββ mint.json
Note: We may continue reading about using the cli, with more examples and commands.
The launching word: start
Yeah! Mint as a framework has a built-in development server:
$ mint-lang start
Mint - Running the development server
βββββββββββββββββββββββββββββββββββββββββββββββββ
β Ensuring dependencies... 5.621ms
β Parsing files... 4.709ms
β Development server started on http://127.0.0.1:3000/
Visiting localhost:3000
will present a Hello Mint!
page.
Let's count 1 2 3
So, our application it's going to show a counter with two buttons (for incrementing and decrementing the counter)
First let's create the Counter
component (we are creating the file /source/Counter.mint
):
/* Counter.mint */
component Counter {
fun render : Html {
<div>
<{"Here be a counter!"}>
</div>
}
}
Next we are going to change the (autogenerated) Main
component so that we render the Counter
component:
/* Main.mint */
component Main {
fun render : Html {
<Counter/>
}
}
Note: Don't worry refreshing your browser, Mint takes care of that:
...
β Files changed recompiling... 8.832ms
Let's continue with the store
and then we will finish the component.
The Store π¦
We will define the counter store like this:
/* CounterStore.mint */
store Counter.Store {
state count : Number = 0
fun increment : Promise(Never, Void) {
next { count = count + 1 }
}
fun decrement : Promise(Never, Void) {
next { count = count - 1 }
}
}
Note: The store is defined in the file /source/CounterStore.mint
Some references for the above code:
Now, let's connect the Counter.store
to the component.
The Component
We started writing an initial implementation of the Counter's component
. Then we implement the store
. Now we need to connect the component
to that store
:
/* Counter.mint */
component Counter {
connect Counter.Store exposing { count }
fun render : Html {
<div>
<{"Here's the count: #{count}"}>
</div>
}
}
Great! That was intuitive and easy! π€
Buttons and Events
It's time to add the buttons to increment/decrement the counter. Taking into account that when clicking a button we need to handle the event, and then use the proper function defined in the store
so that the action reflects on the counter (i.e. the store is updated)
/* Counter.mint */
component Counter {
connect Counter.Store exposing {
count,
increment as incrementCounter,
decrement as decrementCounter
}
fun handleClickOnDecrement (event : Html.Event) : Promise(Never, Void) {
decrementCounter()
}
fun handleClickOnIncrement (event : Html.Event) : Promise(Never, Void) {
incrementCounter()
}
fun render : Html {
<div>
<button onClick={handleClickOnDecrement}>
"-"
</button>
<div>
<{"Here's the count: #{count}"}>
</div>
<button onClick={handleClickOnIncrement}>
"+"
</button>
</div>
}
}
Let's try it!
Yeah! It's alive!
CSS to my eyes!
To be honest we can't say it's a work of art, visually it lacks of some sort of ... well ... you know ... my eyes hurt!
So let's create a better layout π and put some colors π¨, nothing too fancy. For this we are going to use simple CSS.
We are modifying /source/Main.mint
:
component Main {
style base {
font-family: sans;
font-size: 18px;
}
fun render : Html {
<div::base>
<Counter />
</div>
}
}
and /source/Counter.mint
:
/* Counter.mint */
component Counter {
connect Counter.Store exposing {
count,
increment as incrementCounter,
decrement as decrementCounter
}
style base {
display: flex;
}
style baseButton {
color: white;
border: 0;
margin: 0 7px 0;
font-size: 12px;
font-weight: bold;
}
style decrementButton {
background: red;
}
style incrementButton {
background: #009c00;
}
style count {
margin: 0 7px 0;
}
fun handleClickOnDecrement (event : Html.Event) : Promise(Never, Void) {
decrementCounter()
}
fun handleClickOnIncrement (event : Html.Event) : Promise(Never, Void) {
incrementCounter()
}
fun render : Html {
<div::base>
<button::baseButton::decrementButton
onClick={handleClickOnDecrement}>
"-"
</button>
<div::count>
<{"Here's the count: #{count}"}>
</div>
<button::baseButton::incrementButton
onClick={handleClickOnIncrement}>
"+"
</button>
</div>
}
}
And the final result π₯
Farewell and see you later
We've reached the end of this amazing journey with Mint! And as the adventurers say:
It's time to rest my friend,
in this mint fresh air night.
Remember this is not an end,
in the morning new adventures shall arrive!
Well, I don't know if they say that ... but they should π
Hope you enjoyed it! Until the next Mint journey!
As always, thanks, thanks, thanks to:
@bcardiff, @diegoliberman and @petti for reviewing this post and improving the code and text!! πππ
Photo by Jonas Weckschmied on Unsplash
Top comments (0)