Framer Cheat Sheet: Classes & Modules

Classes and modules help you reuse the same element over and over again without duplicating code. And if you put it in a module, you can use it in different prototypes too! This is recommend for users with more experience.

Tess Gadd
Designing Humans
8 min readMar 19, 2018

--

Shit guys. Things just got real. We are building classes and modules. Hot damn. But calm down, it’s not as difficult as it sounds. Even for me, a professional copy-and-paster, can figure it out (well, sort of).

In this cheat sheet we will cover:

  1. What is a class? And a module?
  2. Setting up a class
  3. Creating defaults
  4. Add more layers in a class
  5. Adding new properties
  6. Functions and events
  7. Setting properties outside of initialization (Getters and Setters)
  8. Making a module
  9. Examples
  10. Resources that really helped me

1. What is a class? And a module?

You know PageComponent , ScrollComponent , SliderComponent ? Well, they are all just classes built into Framer.

Great. So what does that mean for you? Basically, by building your own class, you can reuse the same code over and over again in different contexts.

This helps keep consistency through a prototype (or across multiple prototypes), as well as saving you from re writing whole chunks of code for functionality.

A module is a file that we use to keep and organise our classes. Imagine you you had 10 classes in the same Framer file — it would be nuts! So by putting our classes in a module, we keep everything neater, and it also allows us to move the same class to future projects easier.

2. Setting up a class

To set up the basic of most basic classes, you need to do three things;

  1. Define a class
  2. Create a constructor
  3. Create a super

And then call your class.

For the most part you will be able to copy and paste this slab of code before you start creating your own. (But you will need to change the name of MyNewAndImprovedLayer)

class MyNewAndImprovedLayer extends Layer
constructor: (@options={}) ->
super @options
thing = new MyNewAndImprovedLayer

Pro Tip: See how it says, extends Layer? You can extend other components by just saying extends ScrollComponent or whatever. I use extends TextLayer when I want to create a universal label, for example.

A note on etiquette when creating classes, always have your class’ name in CamelCase. For example, don’t name your class button , name it Button. Textfield isn’t any good either, rather TextField. That way it doesn’t get confused with other layers.

3. Creating defaults for the parent layer of the class

So, before we begin — there are two types of defaults. Those you can change outside of the class and those you can’t.

And it all comes down to the ?= and =.

In the below example I have used an = to say that the background colour is black. And you CAN’T change it later. Notice how in the example below that thing’s background colour isn’t blue.

class MyNewAndImprovedLayer extends Layer
constructor: (@options={}) ->
@options.backgroundColor = "#000"
super @options
thing = new MyNewAndImprovedLayer
backgroundColor: "blue"
thing.center()

In this example below, I have used the ?= which means that you will be able to change the backgroundColor outside of the class. See how the code is almost exactly the same.

class MyNewAndImprovedLayer extends Layer
constructor: (@options={}) ->
@options.backgroundColor ?= "#000"
super @options
thing = new MyNewAndImprovedLayer
backgroundColor: "#blue"
thing.center()

Pro Tip: To do a whole lot of defaults in one go, see below. Note: you will be able change these properties outside of the class.

class MyNewAndImprovedLayer extends Layer
constructor: (@options={}) ->
_.defaults @options,
backgroundColor : "#000"
height: 48
borderRadius : 2
super @optionsthing = new MyNewAndImprovedLayer
backgroundColor: "#00aeff"

4. Add more layers in a class

You know how in a slider component you refer to the slider’s knob as slider.knob. ? What you are doing here is referring to a layer within the slider component.

To create a layer that can be accessed outside of the class, add an @ symbol before the layer name. In this example below we are creating a new text layer for a button.

NOTE: You only define the parent for the added layer AFTER the super, along with it’s position.

class Button extends Layer
constructor: (@options={}) ->

@options.backgroundColor ?= "#000"
@options.height = 44

@label = new TextLayer
fontSize: 16

super @options

@label.parent = @
@label.center()
button = new Button
button.center()
button.label.text = "Hello there"

5. Adding new properties

You ever notice how sliderComponents have a min and max property, while most other components don’t? This is a property that has been added.

In this example, we are going to make a very VERY crude version of the TextLayer . The property mySuperSexyFont doesn’t mean anything in code (in fact, in this example you could replace it with HotPants and it wouldn’t change anything).

class SimpleTextLayer extends Layer
constructor: (@options={}) ->
@options.backgroundColor = "000"
@options.mySuperSexyFont ?= "'Source Sans', sans serif"
@options.html = @options.text
@options.style =
fontFamily : @options.mySuperSexyFont
textAlign: "center"
lineHeight: "200px"

super @options

myText = new SimpleTextLayer
text: "hello"
mySuperSexyFont: "'Roboto', sans serif"
myText.center()

6. Functions and events

While you can build events within the constructor of the class, it is neater and more useful to build them outside. Unlike a normal function, use : => as opposed to = ->.

class Button extends Layer
constructor: (@options={}) ->
@options.backgroundColor = "#F14676" super @options #event
@.onMouseOver @Hover
@.onMouseOut @HoverOff
#function
Hover: =>
@.brightness = 70
HoverOff: =>
@.brightness = 100
button = new Button
button.center()

7. Setting properties outside of initialization (Getters and Setters)

So you can add new properties in a class — but how do you change them later? Enter Getters and Setters.

In this example below, we are setting the default for the class to be enabled. Later in the prototype we might want to change it’s class to be disabled — in this case it is onClick .

class Button extends Layer
constructor: (@options={}) ->

@options.disabled ?= false
@options.backgroundColor = "000"
if @options.disabled is true
@options.opacity = 0.5
super @options @define 'disabled',
get: ->
@options.disabled
set: (value) ->
@options.disabled = value
if @options.disabled is true
@opacity = 0.5
else
@opacity = 1


Button = new Button
deactiveButton = new TextLayer
text: "deactive"
deactiveButton.onClick ->
Button.disabled = true

8. Making a module

Making a module would be easy — if it wasn’t for all the moving parts. There are two ways to set up a module, and it depends on the amount of classes you have. If you only have one class, choose method 1, if you have more choose method 2.

But, first download Sublime.

1. If you only have one class in the module

In this example we will be making a “button” module. Please for the Love of all things chocolate and holy, change it to your own module’s name.

  1. Once you have downloaded Sublime, copy and paste your class from Framer into a blank Sublime document.
  2. Where you have class Button extends Layer or whatever, change it to class exports.Button extends Layer
  3. Save your Sublime file as the SAME (exact same) name as your class. e.g. if you class’ name is Button save your module’s name as Button.
  4. Next, create a new framer file and drop the module in the module’s folder.
  5. Now make sure your module’s format is in coffee script. You do this by right clicking on the file and renaming it to e.g. Button.coffee
  6. Now switch over to your Framer file and add {Button} = require "Button" at the top of your file.
  7. Then call your class by just saying button = new Button

2. If you have two or more classes in your module

In this example we will be making a module with a few different form field components. Like something that would help keep consistency across different prototypes through out a company.

  1. Once you have downloaded Sublime, copy and paste your classES into a Sublime blank page.
  2. For each instance where you have class textField extends Layer or whatever, change it to class exports.textField extends Layer . Do this for EVERY class that you want to import.
  3. Save your Sublime file as something that doesn’t relate to any of the classes in your file. For this example we will use MaterialComponents.
  4. Next create a new framer file and drop the module in the module’s folder.
  5. Now make sure your module’s format is in coffee script. You do this by right clicking on the file and renaming it to e.g. MaterialComponents.coffee
  6. Now switch over to your Framer file and add MaterialComponents = require ‘MaterialComponents' at the top of your file. Notice how it is different than if you were just importing one class
  7. Now to call on a class go, button = new MaterialComponents.Button or formField = new MaterialComponents.TextField . Notice how you have to call the module AND the class.

9. Examples

Button Class

This is just a class for a button. The class is within the Framer code — not tucked away in a module.

https://framer.cloud/NQIYw

Button Module

Seeing double? Yes, this does look exactly like the above example — because it kinda is. Except it has the class tucked away in a module.

https://framer.cloud/lWKTD

MaterialComponents Module

This is a massive module I made with more bugs than an anthill — especially around the form fields. But it is a good example of how you can put loads of classes in one module. Read more about it here.

https://framer.cloud/JJGwi

10. Resources that really helped me

Figuring things out for yourself isn’t easy. These two stories really helped me along the way, and hopefully they will help you too.

Developing a Framer Module

This article written by John Marstall really helped me when I was trying to figure things out. Go over and give him 50 claps for me won’t you?

Classes, Loops and Arrays in Framer

Øyvind Nordbø’s article had some great examples of classes and how they can work practically. Go give him some love.

--

--