|
| 1 | +> NOTE: We have yet to publish our initial release to npm. However, once we do, the installation |
| 2 | +instructions will work. |
| 3 | + |
| 4 | +# Getting Started |
| 5 | + |
| 6 | +This guide will help you get started using MDLv2 on your own sites and within your own projects. |
| 7 | + |
| 8 | +> If you are interested in integrating MDLv2 into a framework, or building a component library for |
| 9 | +your framework that wraps MDLv2, check out our [framework integration guide](./integrating-into-frameworks.md). |
| 10 | + |
| 11 | +## MDL Quickstart: Building a simple greeting app |
| 12 | + |
| 13 | +The best way to learn any new technology is to get your hands dirty and build something with it, so |
| 14 | +that's what we'll do here! We'll be building a simple web page which lets you enter a first and/or |
| 15 | +last name, and then greets you using your name. You can see a finished example [here](https://plnkr.co/edit/ahd84pIgOF7OTKgavvPP?p=preview). |
| 16 | + |
| 17 | +As you go through this guide, we encourage you to code along with it. By the end, you will have |
| 18 | +learned the fundamentals incorporating MDLv2 into simple sites, as well as worked with some of the |
| 19 | +components we have to offer. |
| 20 | + |
| 21 | +### Setting up the project |
| 22 | + |
| 23 | +First, let's set up our project. Throughout this guide, we'll assume you have a recent version of |
| 24 | +[NodeJS](https://nodejs.org/en/) and [npm](https://www.npmjs.com/) available on your `$PATH`. You can get the latest NodeJS download [here](https://nodejs.org/en/download/), or use a |
| 25 | +tool like [nvm](https://github.com/creationix/nvm) to install it. |
| 26 | + |
| 27 | +Once node is installed, create a directory for the site and install MDLv2 inside of it. |
| 28 | + |
| 29 | +``` |
| 30 | +mkdir greeting-app |
| 31 | +cd greeting-app |
| 32 | +npm init -y # adds a package.json file into the directory |
| 33 | +npm install --save material-design-lite |
| 34 | +``` |
| 35 | + |
| 36 | +This will install MDLv2 into the `node_modules` folder inside of the `greeting-app` directory. |
| 37 | + |
| 38 | +While we're at it, let's also install [live-server](http://tapiov.net/live-server/) so we can |
| 39 | +develop our greeting app using a local server, and have it automatically reload when we make |
| 40 | +changes. |
| 41 | + |
| 42 | +``` |
| 43 | +npm install --global live-server |
| 44 | +``` |
| 45 | + |
| 46 | +The `--global` flag tells npm to install the package globally, so that the `live-server` program |
| 47 | +will be available on your path. |
| 48 | + |
| 49 | +### Creating the skeleton index.html file |
| 50 | + |
| 51 | +Now that we have a sane environment set up, let's create a simple `index.html` file and include |
| 52 | +the assets needed for MDLv2. Put the following within `index.html` in the `greeting-app` directory: |
| 53 | + |
| 54 | +```html |
| 55 | +<!DOCTYPE html> |
| 56 | +<html class="mdl-typography"> |
| 57 | + <head> |
| 58 | + <meta charset="utf-8"> |
| 59 | + <meta name="viewport" content="width=device-width,initial-scale=1"> |
| 60 | + <title>Greeting App</title> |
| 61 | + <link rel="stylesheet" href="/node_modules/material-design-lite/dist/material-design-lite.css"> |
| 62 | + </head> |
| 63 | + <body> |
| 64 | + <h1 class="mdl-typography--display1">Hello, World!</h1> |
| 65 | + <button type="button" class="mdl-button mdl-button--raised mdl-button--primary"> |
| 66 | + Press Me |
| 67 | + </button> |
| 68 | + </body> |
| 69 | +</html> |
| 70 | +``` |
| 71 | + |
| 72 | +To view the page, run `live-server` within the `greeting-app` directory. This will open up your |
| 73 | +browser to the URL which is serving our `index.html` file. You can leave `live-server` running for |
| 74 | +the duration of this guide. |
| 75 | + |
| 76 | +Let's take a look at a few aspects of the above HTML. |
| 77 | + |
| 78 | +* **No javascript necessary (yet)** - Because we aren't using any dynamic components, we only need |
| 79 | + to include the MDLv2 CSS so that we can apply the proper CSS classes to our elements. With MDLv2, |
| 80 | + javascript is only necessary for dynamic components whose UI needs to be made aware of events |
| 81 | + happening on the page which can't be hooked into using CSS. As we develop our greeting app, we'll |
| 82 | + add in the necessary javascript. |
| 83 | +* **No automatic DOM rendering** - For all components, MDL does not render _any_ DOM elements |
| 84 | + itself. MDLv2 is similar to [Bootsrap](http://getbootstrap.com/) in this respect; it expects rhe end user to render the DOM |
| 85 | + and provide the proper CSS classes. This avoids a litany of problems for integrating MDL into |
| 86 | + complex applications. |
| 87 | +* **Elements are not natively styled** - Notice how above, we give the `<html>` element a class of |
| 88 | + `mdl-typography`, the `<h1>` element a class of `mdl-typography--display1`, and the button a class |
| 89 | + of `mdl-button`, along with multiple _modifier classes_. We _never_ make any assumptions about |
| 90 | + which elements are being used for our components, instead relying on CSS classes for maximum |
| 91 | + flexibility. Our CSS class names follow a slightly modified version of the [BEM](http://getbem.com/) system. |
| 92 | + |
| 93 | +### Adding in javascript for dynamic components |
| 94 | + |
| 95 | +Now that we've gotten the gist of MDLv2, let's build our greeting app. The app consists of |
| 96 | +two input fields for a first and last name, as well as a submit button. Because Material Design |
| 97 | +text input fields contain a lot of functionality, we must include javascript to provide a |
| 98 | +full-fidelity experience for them. Furthermore, it would be nice if our submit button featured a |
| 99 | +ripple effect. We can include that using javascript as well. |
| 100 | + |
| 101 | +> Note that we currently have an [issue out](https://github.com/google/material-design-lite/issues/4614) to integrate ripples directly into buttons. |
| 102 | +
|
| 103 | +Replace the contents of the `<body>` tag in `index.html` with the following: |
| 104 | + |
| 105 | +```html |
| 106 | +<main> |
| 107 | + <h1 class="mdl-typography--display1">Tell us about yourself!</h1> |
| 108 | + |
| 109 | + <form action="#" id="greeting-form"> |
| 110 | + <div> |
| 111 | + <div class="mdl-form-field"> |
| 112 | + <div class="mdl-textfield" data-mdl-auto-init="MDLTextfield"> |
| 113 | + <input id="firstname" type="text" class="mdl-textfield__input"> |
| 114 | + <label for="firstname" class="mdl-textfield__label"> |
| 115 | + First Name |
| 116 | + </label> |
| 117 | + </div> |
| 118 | + </div> |
| 119 | + |
| 120 | + <div class="mdl-form-field"> |
| 121 | + <div class="mdl-textfield" data-mdl-auto-init="MDLTextfield"> |
| 122 | + <input id="lastname" type="text" class="mdl-textfield__input"> |
| 123 | + <label for="lastname" class="mdl-textfield__label"> |
| 124 | + Last Name |
| 125 | + </label> |
| 126 | + </div> |
| 127 | + </div> |
| 128 | + </div> |
| 129 | + |
| 130 | + <button type="submit" |
| 131 | + class="mdl-button |
| 132 | + mdl-button--raised |
| 133 | + mdl-button--primary |
| 134 | + mdl-ripple-surface" |
| 135 | + data-mdl-auto-init="MDLRipple"> |
| 136 | + Print Greeting |
| 137 | + </button> |
| 138 | + </form> |
| 139 | + |
| 140 | + <!-- The p element below is where we'll eventually output our greeting --> |
| 141 | + <p class="mdl-typography--headline" id="greeting"></p> |
| 142 | +</main> |
| 143 | + |
| 144 | +<script src="/node_modules/material-design-lite/dist/material-design-lite.js"></script> |
| 145 | +<script>window.mdl.autoInit();</script> |
| 146 | +``` |
| 147 | + |
| 148 | +If you save the file return to your browser, you'll now see that we have two very nicely styled |
| 149 | +form fields, as well as a button that - when pressed - displays a material ink ripple, albeit a |
| 150 | +very subtle one. We'll be taking care of that shortly. For now, let's go back and take a look at |
| 151 | +what we just wrote. |
| 152 | + |
| 153 | +The two main things to notice are the `data-mdl-auto-init` attributes, as well as the final script |
| 154 | +tag, which simply calls `window.mdl.autoInit()`. Unlike MDLv1, **MDLv2 does not |
| 155 | +instantiate any components automatically.** This avoids the headaches involved with hacking around |
| 156 | +lifecycle handlers that we saw with MDLv1 when trying to use it within more complex sites. |
| 157 | + |
| 158 | +When `mdl.autoInit()` is called, it looks for all elements with a `data-mdl-auto-init` attribute, |
| 159 | +and attaches the MDL JS Component with the given class name to that element (the actual |
| 160 | +mechanics are a bit more complicated, but for now this is essentially all you need to understand about |
| 161 | +what it's doing). So when it sees `MDLTextfield`, it instantiates a [MDLTextfield](../packages/mdl-textfield) instance |
| 162 | +to the corresponding elements. It does the same thing for the button, attaching a [MDLRipple](../packages/mdl-ripple) |
| 163 | +instance to the element. |
| 164 | + |
| 165 | +It is worth noting that `mdl.autoInit` is provided _purely_ as a convenience function, and is not |
| 166 | +required to actually use the components. It is, however, the simplest way to get up and running |
| 167 | +quickly, and recommended for static sites that use the comprehensive `material-design-lite` library. |
| 168 | +Speaking of which, this is a great time to talk about a fundamental aspect of MDLv2: |
| 169 | + |
| 170 | +#### All components are modular |
| 171 | + |
| 172 | +Although when we initially set up this project we installed the `material-design-lite` package, that |
| 173 | +package is simply a thin wrapper around individual component packages, such as [mdl-typography](../packages/mdl-typography), [mdl-button](../packages/mdl-button), [mdl-textfield](../packages/mdl-textfield), and [mdl-ripple](../packages/mdl-ripple). |
| 174 | +Even the `autoInit()` function [lives in its own package](../packages/mdl-auto-init), which the |
| 175 | +`material-design-lite` package uses to register all of the individual components to their names used |
| 176 | +within `data-mdl-auto-init`. Each component can be used as a standalone package, and can be mixed |
| 177 | +and matched at will. This allows for custom builds requiring the minimum possible amount of CSS/JS |
| 178 | +code. It also means that MDLv2 works extremely well with module loading systems and modern |
| 179 | +front-end toolchains. |
| 180 | + |
| 181 | +### Adding the business logic |
| 182 | + |
| 183 | +Finally, let's add our (very simple) business logic to the bottom of the page, which intercepts the |
| 184 | +form submission and uses the input field values to print out an appropriate greeting. Add the |
| 185 | +following below the last `<script>` tag within the `<body>`: |
| 186 | + |
| 187 | +```html |
| 188 | +<script> |
| 189 | + document.getElementById('greeting-form').addEventListener('submit', function(evt) { |
| 190 | + evt.preventDefault(); |
| 191 | + var firstname = evt.target.elements.firstname.value; |
| 192 | + var lastname = evt.target.elements.lastname.value; |
| 193 | + var greeting = 'Hello'; |
| 194 | + if (firstname || lastname) { |
| 195 | + greeting += ', '; |
| 196 | + if (firstname && lastname) { |
| 197 | + greeting += firstname + ' ' + lastname; |
| 198 | + } else if (lastname) { |
| 199 | + greeting += 'Mx. ' + lastname; |
| 200 | + } else { |
| 201 | + greeting += firstname; |
| 202 | + } |
| 203 | + } |
| 204 | + greeting += '!'; |
| 205 | +
|
| 206 | + document.getElementById('greeting').textContent = greeting; |
| 207 | + }); |
| 208 | +</script> |
| 209 | +``` |
| 210 | + |
| 211 | +When you save the file and the page reloads, you should be able to type your name into the form, |
| 212 | +hit the button, and get a pleasant greeting :wave: |
| 213 | + |
| 214 | +### Changing the Theme |
| 215 | + |
| 216 | +You may have noticed that the button background, as well as the label and underline on focused text |
| 217 | +input fields, defaults to the Indigo 500 (`#673AB7`) color from the [Material Design color palette](https://material.google.com/style/color.html#color-color-palette). |
| 218 | +This is part of the default theme that ships with MDL; it uses Indigo 500 for a primary color, and |
| 219 | +Pink A200 (`#FF4081`) for an accent color. Let's change the theme's primary color. |
| 220 | + |
| 221 | +A common misconception when implementing Material Design is that the colors you use _must_ come from |
| 222 | +the Material Palette. This is not true at all. The only defining guideline for color within Material |
| 223 | +Design is that it has "bold hues juxtaposed with muted environments, deep shadows, and bright |
| 224 | +highlights". Let's change our theme's primary color to `#0E4EAD`, the "Afternoon_Skyblue" color from |
| 225 | +the [Deep_Skyblues Colourlovers Palette](http://www.colourlovers.com/palette/334208/Deep_Skyblues). |
| 226 | + |
| 227 | +The easiest way to change the theme of an MDLv2 application is via [CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). Simply add the |
| 228 | +following to the `<head>` tag of `index.html`: |
| 229 | + |
| 230 | +```html |
| 231 | +<style> |
| 232 | + :root { |
| 233 | + --mdl-theme-primary: #0e4ead; |
| 234 | + } |
| 235 | +</style> |
| 236 | +``` |
| 237 | + |
| 238 | +If you are using any modern browser besides Edge (which is currently [working on it](https://developer.microsoft.com/en-us/microsoft-edge/platform/status/csscustompropertiesakacssvariables/)), you'll see that the button background as well as the focused underline and label on text |
| 239 | +fields are now a nice, dark shade of blue. |
| 240 | + |
| 241 | +> Note that using CSS Variables is just one way of theming using MDLv2. Check out our |
| 242 | +[theming documentation](./theming.md) _(coming soon!)_ for more info. |
| 243 | + |
| 244 | +### Finishing Touches: Adding some custom styles |
| 245 | + |
| 246 | +Every site is different, and we cannot hope to build a user interface library that |
| 247 | +anticipates every design choice a user may want. Because MDLv2 uses plain old CSS, it is |
| 248 | +trivial to customize and modify its styles to your liking. Let's change the ripple color to be a |
| 249 | +more opaque shade of white, as well as add some auxiliary styles to bump up the vertical spacing |
| 250 | +between the form fields and the submit button. Add the following to the `<style>` tag within |
| 251 | +`<head>`: |
| 252 | + |
| 253 | +```css |
| 254 | +.mdl-ripple-surface.mdl-ripple-upgraded.mdl-button--primary::before, |
| 255 | +.mdl-ripple-surface.mdl-ripple-upgraded.mdl-button--primary::after { |
| 256 | + background-color: rgba(255, 255, 255, .2); |
| 257 | +} |
| 258 | + |
| 259 | +#greeting-form > button { |
| 260 | + margin-top: 8px; |
| 261 | +} |
| 262 | +``` |
| 263 | + |
| 264 | +Congrats! You've built your first MDLv2 app! In the process, you've learned the basics of MDL, |
| 265 | +how to easily add components to a page, and how to customize and theme MDL to your liking. |
| 266 | + |
| 267 | +## Next Steps |
| 268 | + |
| 269 | +If you're looking to incorporate MDL Components into a framework like Angular or React, check our |
| 270 | +[framework integration guide](./integrating-into-frameworks.md). You can also take a look at our |
| 271 | +[examples](../examples) directory which contains examples integrating MDLv2 components into popular |
| 272 | +front-end frameworks. It also shows how you can use our source ES2015 and SCSS files directly within |
| 273 | +your own code, for maximum flexibility, modularity, and code size reduction. |
| 274 | + |
| 275 | +If you'd like to contribute to |
| 276 | +MDLv2 and build your own components, or extend one of ours to fit your own purposes, check out our |
| 277 | +guide on [how to build a component](./how-to-build-a-component.md). |
0 commit comments