Try Install Learn Blog API Packages GitHub
Posts

Mint 0.9.0 Monday, April 6th, 2020

Mint 0.9.0 has been released!

This release comes with changes to the type system, bug fixes and support for CSS at rules.

There are 68 commits since 0.8.0 by 7 contributors.

Let’s review some highlights in this release. But don’t miss out on the rest of the release changelog which has a lot of valuable information.

Optional Type Signatures

There are some type signatures which can be inferred by the type-checker but are required to write in 0.8.0:

  • return type of a function
  • type of a computed property
  • type of a state variable
  • type of a property

These types are optional in 0.9.0 and their types are inferred if not provided:

component Main {
  property firstName = "John"

  state lastName = "Doe"

  get fullName {
    "#{firstName} #{lastName}"
  }

  fun updateLastName (name : String) {
    next { lastName = name }
  }

  fun render {
    <div>
      <{ fullName }>
    </div>
  }
}

This change will make the code more readable by reducing the visual complexity, and will make developers more productive.

Type Specifiation

It is now possible to specify the type of an array literal or an inline JavaScript code.

This is not a type cast, it's just to help the type checker in certain cases.

Array Literal

To specify the type of an array use the of keyword followed by the type of its items:

[] /* Array(a) */
[] of String /* Array(String) */

This can be done for array literals which contain values as well:

["A", "B"] of String /* Array(String) */

This is useful in situations where the type of the array needs to be specified, for example when two records has multilpe arrays and would both match a generic structure:

record User {
  projects : Array(Project)
}

record Guest {
  projects : Array(GuestProject)
}

/* This could match either and would resolve to User */
{ projects: [] }

/* This will resolve to Guest */
{ projects: [] of GuestProject }

Inline JavaScript

To specify the type of an inline JavaScript code use the as keyword:

`"Hello World!"` as String

Type Constructors

Records can now be constructed using a type constructor which is a function with the same name as the record and which takes the values of the fields as parameters and returns a record:

record User {
  name : String,
  age : Number,
  active : Bool,
}

User("John Doe", 32, true) == {
  name = "John Doe",
  active = true,
  age = 32
}

The order of the parameters are in the same as the order the fields.

This function can be partially applied as well:

record User {
  name : String,
  age : Number,
  active : Bool,
}

try {
  partial =
    User("John Doe", 32)

  partial(true) == {
    name = "John Doe",
    active = true,
    age = 32
  }
}

Required Properties

It is now possible to omit the default value of a property, making it required:

component User {
  property name : String

  fun render {
    <div>
      "User: #{name}"
    </div>
  }
}

If a required property is not provided the type checker will show you an error.

A property needs to have either a default value or a type signature to determine its final type:

/* These are valid */
property name : String = "Joe"
property name : String
property name = "Joe"

/* This is not valid and will show an error. */
property name

CSS At Rules

Up until this point the @media rule was the only one supported. In this release @font-face , @supports and @keyframes rules are supported as well.

Supports

@supports rules can be used the same way as @media rules, it can be nested into other rules and can contain interpolations.

component Main {
  style base {
    @supports (display: grid) {
      div {
        display: grid;
      }
    }
  }

  fun render : Html {
    <div::base>
      "Hello!!!"
    </div>
  }
}

Keyframes

@keyframes rules can be defined inside style blocks but they are considered global, they can't be nested into other selectors but can contain interploations.

component Main {
  style base {
    @keyframes fade-in {
      from {
        opacity: 0;
      }

      to {
        opacity: 1;
      }
    }

    animation: fade-in 1s linear;
  }

  fun render : Html {
    <div::base>
      "Hello!!!"
    </div>
  }
}

Font Face

@font-face rules can be defined inside style blocks but they are considered global, because of that they can't have interpolations and they can't be nested into other selectors.

component Main {
  style base {
    @font-face {
      src: url(sansation_light.woff);
      font-family: myFirstFont;
    }

    font-family: myFirstFont;
  }

  fun render : Html {
    <div::base>
      "Yey!!!"
    </div>
  }
}

Next steps

Please update your Mint and report any issues. We will keep moving forward and start the development focusing on 0.10.0.