Introducing the MaterialComponents module

Easily create, use and modify various Material Design components using this simple module. All of the components are design according to the Material Design Guidelines — hopefully making your prototyping life a little bit easier.

Tess Gadd
Designing Humans
13 min readNov 14, 2017

--

My pet project for the last few months has been to build a Material Design inspired components module — why? Because some of them are kinda hard to build and get right.

To download the module just go here:

https://github.com/TessGadd/MaterialComponents

— FULL DISCLOSURE —

  1. While I tried to follow the Material Design guidelines as closely as possible — I probably made a mistake here or there where it doesn’t follow the guidelines exactly. If you see something that isn’t right — be a doll and let me know in the comments.
  2. This is my first module that I have shared — and there are still lots (x100) of bugs, especially where icons are involved. If you spot a bug — better yet, if you know how to fix one — be a honey and let me know in the comments.

Formalities out of the way — shall we get right into it?

In this post, we will cover the following:

  1. How to import the MaterialComponents module
  2. General properties
  3. Color
  4. TextField_Basic
  5. TexField_Validation
    a) Email
    b) Password for Login (specific answers)
    c) Password for Register (pattern)
  6. TextArea
  7. TextField_Dropdown
  8. Checkboxes
  9. RadioButtons
  10. Switch
  11. RaisedButton
  12. FlatButton
  13. FAB
  14. AppBar
  15. Demos
  16. Coming soon…
  17. A word from me :)

1. How to import a module

The first time you import a module, you feel like you are doing something strange and complicated. In reality, it isn’t that difficult.

First, what is a module? In essence, a module is a file that you can keep in a separate folder and that your code refers to. This keeps your primary code looking slick and shiny.

  1. Download the MaterialComponents file off GitHub. Click the button that says clone / download then in the dropdown, click download ZIP.
  2. Once you have downloaded the file, look for the MaterialComponents.coffee file.
  3. Put this file in the modules folder of your prototype. (This is assuming that you have already created and saved your Framer prototype file).

4. Now you need to tell your prototype to refer to the module. To do this, in your Framer file, add the following line of code:

MaterialComponents = require 'MaterialComponents'

5. To see a raised button, just add the following:

MaterialComponents = require 'MaterialComponents'button = new MaterialComponents.RaisedButton

2. General Properties

Through out the module I have tried to used consistent properties to make it easier for you (the lovely user of said module) to use. Below are some of these properties and what they mean.

theme

In Material Design, there are two themes, namely “light” and “dark”. When you say that your component is “dark”, it means that the background it sits on is a dark color, hence it needs to be light and visa versa. By default, the theme is set to “light”.

themeColor

themeColor refers to what color the featured elements should be and not the core elements. By featured elements I mean, e.g. the color of the switch’s thumb and not it’s label, the color of the line on a selected text field and not the input of the text itself, etc.

labelText
This is a bit self explanatory, but this is setting for the text value on the label of the element.

disableRipple
Some components (checkboxes, buttons, switches, etc) have ripples that appear when you click them — but these are optional so you can just set this property to false if you would rather not have them.

3. Colors

This section allows you to easily import the correct Material Design colors.

This is just a brief intro into the Material Design color palette — for a more in depth understanding — I highly recommend shimmying on over to the Material Design Color page for a better understanding.

In essence, the MDG has 19 base colors (excluding white and black), and 14 variations of those colors (grey, brown and blue grey only have 10).

For the purposes of this module, the base colors are: red, pink, purple, deepPurple, indigo, blue, lightBlue, cyan, teal, green, lightGreen, lime, yellow, amber, orange, deepOrange, brown, grey, blueGrey.

For the purposes of this module, the variations of these colors are: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400, A700. brown, grey and blueGrey do not have variations: A100, A200, A400, A700.

So you can call on these colors by using the color name and variation; teal600 or blueGrey100 .

You can also call on label / line colors too. There are two themes light and dark, followed by either Primary, Secondary or Disabled. So if you have a light theme and want to make a headline, use lightPrimary .

Note: red500 is the same as red, pink500 is the same as pink , etc; because the 500s variations are the primary color.

MaterialComponents = require 'MaterialComponents'circle1 = new Layer
backgroundColor: MaterialComponents.purple100
circle2 = new Layer
backgroundColor: MaterialComponents.purple
circle3 = new Layer
backgroundColor: MaterialComponents.purple900
label = new TextLayer
color: MaterialComponents.darkPrimary

MaterialComponents Color Cheat Sheet coming soon

4. TextField_Basic

Ah, the humble text field. Arguably one of the most used components, appearing in most programs, apps and websites — yet there is currently very little support for it Framer, excluding of course Jordan Dobson’s InputField module. In fact, this section of the MaterialComponents module is frankensteined from his version. Let’s have a little (or a big) clap for Jordan.

This is a “ready-to-go” form field which you can use straight away, complete with all the micro interactions.

You can find out more about MD text fields here.

MaterialComponents = require 'MaterialComponents'#default (left)
TextField_Basic1 = new MaterialComponents.TextField_Basic
#custom (right)
TextField_Basic2 = new MaterialComponents.TextField_Basic
theme: "dark"
themeColor: MaterialComponents.cyan
labelText: "What is your name?"
helperTextVisble: true
helperText: "You should probably know this one"
TextField_Basic2.on Events.Input, (value, layer) ->
readOut.html = TextField_Basic2.input.value

MaterialComponents.TextField_basic Cheat Sheet coming soon

5. TextField_Validation

This field is based on the one above — except it has validations attached to it. It can validate in two different ways using pattern or match.

pattern uses different patterns to validate whether something is an email address, password, phone number etc. An example of and email pattern is : [a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$ . Check out html5patterns for more.

match needs to be told exactly what value the user has to input. You treat this field the same way you would an array, e.g. match: ["password1", "password2"] . You will generally use this for login screens.

Email

As mentioned before, this field email field will need a pattern to call up the error state.

MaterialComponents = require 'MaterialComponents'TextField_Email = new MaterialComponents.TextField_Validation
theme: "dark"
themeColor: MaterialComponents.green
labelText: "Email"
pattern: "[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$"
helperText: "not a vailid email address"
eyeVisible: false
type: "text"
TextField_Email.on Events.Input, (value, layer) ->
readOut.html = TextField_Email.input.value

Password (for login)

This component requires a match to work. Only use this when you want the user to give very specific answers.

MaterialComponents = require 'MaterialComponents'TextField_Password = new MaterialComponents.TextField_Validation
theme: "dark"
themeColor: MaterialComponents.purple
labelText: "Login password"
helperText: "password does not match username"
match: ["password123"]

TextField_Password.on Events.Input, (value, layer) ->
readOut.html = TextField_Password.input.value

Password (for sign-up)

This field requires a pattern to ‘create’ as password. Don’t forget to add helper text depending on what your password requirements are.

MaterialComponents = require 'MaterialComponents'TextField_Password = new MaterialComponents.TextField_Validation
theme: "dark"
themeColor: MaterialComponents.yellow
labelText: "Sign-up password"
pattern: "(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
helperText: "must contain an uppercase and lowercase letter, a number and must be more than 8 characters"

TextField_Password.on Events.Input, (value, layer) ->
readOut.html = TextField_Password.input.value

MaterialComponents.TextField_Validation Cheat Sheet coming soon

6. TextArea

This module is a real life Frankenstein’s monster seeing that I adapted it from Blaine Billingsley’s AutoGrow module who adapted it from Jordan Dobson’s InputField module and the jQuery Autogrow plugin. Either way, it seems to have survived all the surgeries (somewhat).

According to the MDG, “Text areas are taller than text fields and wrap overflow text onto a new line. They scroll vertically when the cursor reaches the bottom of the field.”

While you can’t really have a validation for large text areas, they are sometimes needed if chatterboxes (what is they written version of a chatterbox?) exceed the character limit.

MaterialComponents = require 'MaterialComponents'#default
TextArea1 = new MaterialComponents.TextArea
#Custo,
TextArea2 = new MaterialComponents.TextArea
theme: "dark"
themeColor: MaterialComponents.orange
limitOn: true
characterLimit: 50
labelText: "Say something sweet..."

MaterialComponents.TextArea Cheat Sheet coming soon

7. TextField_Dropdown

There are loads of different types of dropdowns — so don’t get confused between dropdown buttons, dropdown menus, dropdown pickers and text field dropdowns. All of them are completely different — so let’s focus on the TextField_Dropdown for today.

Radio buttons and text field dropdowns can be used interchangeably depending on how many options you have. If you have a few options, I suggest using radio buttons — otherwise dropdowns are your friend.

Over all, I feel that the MDG have given text field dropdowns very little love — but it you want, you can read more about them here.

MaterialComponents = require 'MaterialComponents'#default
Dropdown = new MaterialComponents.TextField_Dropdown
#custom
Dropdown2 = new MaterialComponents.TextField_Dropdown
theme: "dark"
width: 250
labelText: "What do you want to drink?"
choices: ["Old Fashioned", "Martinez", "Martini", "Daiquiri", "Margarita", "Bloody Mary", "Irish Coffee", "Mint Julep", "Whiskey Sour", "Mai Tai", "Cosmopolitan"]

Dropdown2.bringToFront()

Dropdown2.onClick ->
readOut.html = Dropdown2.activeSelection

NOTE: Always add a .bringToFront() at the end of your prototype to make sure your menu sits above the other other fields.

Also, Old Fashioneds are my favourite drink if you are ever in the area.

MaterialComponents.TextArea Cheat Sheet coming soon

8. Checkboxes

Checkboxes are an often overlooked part of form design — but hopefully, I have made it easier for you to now use them. The way the information is stored here is in an array, so you can see all that the user clicked on.

The MDG says, “Checkboxes allow the user to select multiple options from a set. If you have multiple options appearing in a list, you can preserve space by using checkboxes instead of on/off switches. If you have a single option, avoid using a checkbox and use an on/off switch instead.”

I’m not sure if I agree with the MDG on the bit about rather using a switch if there is only one option — after all, think of the “I have read the T&Cs” checkbox. It would be super weird if it suddenly became a switch. Anyway, I will leave this one up to you and your users.

MaterialComponents = require 'MaterialComponents'#default
Checkboxes1 = new MaterialComponents.Checkboxes
#custome
Checkboxes2 = new MaterialComponents.Checkboxes
screenColor: MaterialComponents.grey900
width: 200
x: Align.center
y: Align.center()
theme: "dark"
themeColor: MaterialComponents.indigo500
labelText: "I am awesome because..."
choices: ["I have chocolate", "I (still) don't like Bieber", "I remembered to eat breakfast"]
disableRipple: true
Checkboxes2.onClick ->
readOut.html = Checkboxes2.activeSelection

NOTE: Don’t forget to set the screenColor to be the same color as the checkboxes’ background.

— BUG —

Depending on what device you are on, sometimes the checks within the checkbox won’t sit in the right place. To fix this, use the following property:

Checkboxes2 = new MaterialComponents.Checkboxes
checkY: 4

MaterialComponents.CheckBoxes Cheat Sheet coming soon

9. RadioButtons

Use this radio button component when you want your user to only select one option, and when you want all the options to be displayed at one time. You can also read out what option has been selected.

In terms of usability, the MDG recommends, “Radio buttons allow the user to select one option from a set. Use radio buttons for exclusive selection if you think that the user needs to see all available options side-by-side. Otherwise, consider a dropdown, which uses less space than displaying all options”

MaterialComponents = require 'MaterialComponents'#default
RadioButtons = new MaterialComponents.RadioButtons
#custom
RadioButtons2 = new MaterialComponents.RadioButtons
theme: "dark"
themeColor: MaterialComponents.orange
labelText: "I am awesome because..."
choices: ["I have chocolate", "I (still) don't like Bieber", "I remembered to eat breakfast"]
disableRipple: true

RadioButtons2.onClick ->
readOut.html = RadioButtons2.activeSelection

MaterialComponents.RadioButtons Cheat Sheet coming soon

10. Switch

The humble switch only really makes an appearance in the settings section according to the Material Design Guidelines. Also, a point to note is that they suggest that, unlike the other components, when you have a switch on a dark theme, rather use a color within the 300 variations as opposed to the 500s.

According to the MDG, “On/off switches toggle the state of a single settings option.”

MaterialComponents = require 'MaterialComponents'#default
Switch = new MaterialComponents.Switch
#custom
Switch2 = new MaterialComponents.Switch
theme: "dark"
themeColor: MaterialComponents.pink300
labelText: "airplane"
disableRipple: true
activeOnStart: true
Switch2.onClick ->
readOut.html = Switch2.active

MaterialComponents.Switch Cheat Sheet coming soon

11. Raised Button

I love big buttons and I can not lie — you other brothers can’t deny, -

Ok — I will stop before it gets worse.

I have a (not so) secret love for buttons. But making buttons comes with a big responsibility. Because a button without interactions are just short of happy. It’s like an ice cream without a cherry, or hot chocolate without marshmallows, or a piña colada without an umbrella. So please, for the love of UI, give your buttons micro interactions.

According to the MDG, “Raised buttons add dimension to mostly flat layouts. They emphasize functions on busy or wide spaces”.

In this module, we have the basic hover interaction, along with a ripple or a direction ripple, and mouse down state.

I also made it possible to have a dense button, which is slightly smaller than a regular button.

MaterialComponents = require 'MaterialComponents'#default that is disabled
RaisedButton_Disabled = new MaterialComponents.RaisedButton
disabled: true
theme: "light"
#default
RaisedButton = new MaterialComponents.RaisedButton
#custom disabled_Button = new MaterialComponents.RaisedButton
disabled: true
theme: "dark"
labelText: "disabled"
directionRipple_button = new MaterialComponents.RaisedButton
directionRipple: true
labelText: "direction Ripple"
themeColor: MaterialComponents.pink400
disableRipple_button = new MaterialComponents.RaisedButton
disableRipple: true
labelText: "disable Ripple"
themeColor: MaterialComponents.yellow
disableRipple_button.label.color = MaterialComponents.grey900
RaisedButton6 = new MaterialComponents.RaisedButton
dense: true
labelText: "dense"
themeColor: MaterialComponents.green400

MaterialComponents.RaisedButton Cheat Sheet coming soon

12. Flat Button

Flat buttons are the slightly over looked sibling of raised buttons. But they do have their place in the world. According to MDG, “flat buttons should be used on toolbars, In dialogs (to unify the button action with the dialog content) or Inline (with padding, so the user can easily find them)”.

MaterialComponents = require 'MaterialComponents'#defaultFlatButton_disabled = new MaterialComponents.FlatButton
disabled: true
theme: "light"

FlatButton = new MaterialComponents.FlatButton
#customdisabled = new MaterialComponents.FlatButton
disabled: true
theme: "dark"
labelText: "disabled"
directionRipple = new MaterialComponents.FlatButton
directionRipple: true
labelText: "direction Ripple"
themeColor: MaterialComponents.pink400
disableRipple = new MaterialComponents.FlatButton
disableRipple: true
labelText: "disable Ripple"
themeColor: MaterialComponents.yellow400
dense = new MaterialComponents.FlatButton
dense: true
labelText: "dense"
themeColor: MaterialComponents.green400

MaterialComponents.FlatButton Cheat Sheet coming soon

13. FAB

FAB, doesn’t stand for “FAbulous Button”, but rather “Floating Action Button” (personally, I still prefer FAbulous Button, but whatever).

The MDG says, “Floating action buttons are used for a promoted action. They are distinguished by a circled icon floating above the UI and have motion behaviors that include morphing, launching, and a transferring anchor point.”

By default, if you are on a screen that has a width of less than 460dp, then it will switch to the mini version of the FAB. Also, by default it will also align your FAB to the bottom of the page using the correct padding, regardless of whether it is a mobile or desktop screen (you can still change the position using the x and y ).

You can change the icon using the icon property with the name of the Material Icon you want to use.

MaterialComponents = require 'MaterialComponents'#default
FAB = new MaterialComponents.FAB
#custom
FAB2 = new MaterialComponents.FAB
mini: true
themeColor: MaterialComponents.pink
icon: "close"

NOTE: You MUST be connected to the internet to import the icon.

MaterialComponents.FAB Cheat Sheet coming soon

14. AppBar

This is a very (VERY) basic app bar and you are invited (BEGGED) to make it your own. By default it picks up whether or not you are on a mobile, and if you are, it will add a status bar at the top. If you want to see the status bar while you are designing, just set mobile to true.

MaterialComponents = require 'MaterialComponents'#default
head1 = new MaterialComponents.AppBar
#custom
head2 = new MaterialComponents.AppBar
mobile: true
themeColor: MaterialComponents.pink
labelText: "Custom"

— BUG —

For some reason, on some device types, the menu and status icons sit in the wrong place. To fix this, use the following properties:

head = new MaterialComponents.AppBar
statusIconsY: Align.center()
menuIconY: Align.center(-1)

15. A few examples

Here are a few examples of the module in the wild.

https://framer.cloud/btVfb

1. Basic Header with a FAB

This is a simple example of a header and a FAB button.

https://framer.cloud/JJGwi

2. Form

This is just a basic form which includes a text field, text area, radio buttons, checkboxes and a raised button.

https://framer.cloud/yxhOC

3. Sign in

This simple prototype just has form field validations for sign in. Here I used the match property.

16. Coming soon

I plan on writing a few cheat sheets and adding the below components. What do you think?

  • Continuous Slider
  • Continuous Range Slider
  • Discrete Slider
  • Discrete Range Slider
  • Text field Search filter

What do you want me to build / write next? Or spot any naught bugs (this is my first published module — so there should be a few (hundred) bugs)? Please leave me a comment below on how to improve.

Also — let me know if this was helpful by giving me a clap (or better yet, an applause). Thank you!

--

--