---
title: 'Ember for Designers: Components'
teaser: 'Part of our ongoing "Ember for Designers" series. Learn how to get started
  with Ember by leveraging components.

  '
tags: web,design,ember for designers,ember
author: Christian Reuter
published_on: 2014-11-24
---

Imagine a world where you aren’t confined to the existing standard for available
HTML tags. You aren’t limited to `<h1>`s and `<div>`s and `<section>`s. You can
define and use your own application-specific DOM elements for more semantic and
readable markup.

The W3C is currently working on a [Custom
Elements](https://w3c.github.io/webcomponents/spec/custom/) specification that
offers that promise, and Ember components make that promise a reality we can use
today. Because Ember components are an early implementation of Custom Elements
and following the spec as closely as possible, what we define today should be
usable in other frameworks tomorrow.

Consider an inline-edit element, which you might use in many places of an
application. With components, you only need to write the markup once to use it
in many contexts.

![Inline Edit](https://images.thoughtbot.com/ember-components/inline-edit-component.gif)

## The Template

To create a new component, make a new template who lives in the `components`
directory.

In `app/templates/components/inline-edit.hbs`:

```handlebars
{{#if editing}}
  <form>
    {{input value=value}}
    <a href="#" {{action "cancelEditing"}}>Cancel</a>
    <a href="#" {{action "stopEditing"}}>Save</a>
  </form>
{{else}}
  <a href="#" {{action "startEditing"}}>{{value}}</a>
{{/#if}}
```

(Note: components must have a dash in their name to prevent collisions with
future <abbr title="HyperText Markup Language">HTML</abbr> elements.)

Our example needs to keep track of editing state, but if your component only
needed markup, you’d be finished. You could already use your custom
`{{inline-edit value=name}}` element wherever you’d like.

## The CSS

While Ember components don’t specifically bundle or attach styling (Custom
Elements can using the [Shadow
DOM](https://w3c.github.io/webcomponents/spec/shadow/)), I like having a
stylesheet per component. I’d create a corresponding
`app/styles/components/_inline-edit.scss` to keep everything nice and tidy.

## The Class

You can optionally extend components with properties, variables and actions by
creating a component subclass.

For the inline-edit, we’ll want to set set the custom `editing` property’s
default to false, and also define our actions. (I’ll sometimes prototype these
interactions with jQuery, and let a developer come in behind me to move
everything to the component.)

In `app/components/inline-edit.coffee`:

```coffeescript
InlineEditComponent = Ember.Component.extend
  editing: false

  actions:
    startEditing: ->
      @toggleProperty("editing")

    stopEditing: ->
      @toggleProperty("editing")
      if @get("isDirty")
        @get("content").save()

    cancelEditing: ->
      @toggleProperty("editing")
      @get("content").rollback()
```

## Other examples

Components are powerful and composable. They conveniently reflect how I already
think of components in Sass, so I love the symmetry.

We’re using them for avatars in one application, where we sometimes want to
optionally show the username.

```handlebars
{{user-avatar url=user.avatarURL}}
```

or

```handlebars
{{user-avatar url=user.avatarURL showName=true}}
```

You might also use them for reusable parts like
[dropdowns](https://twitter.com/heyjinkim/status/398237979908374528), [form
groups](http://alexspeller.com/simple-forms-with-ember/), or other [navigation
patterns](https://indexiatech.github.io/ember-components/#/component/component.tabs/controller_per_tab).

## Additional Reading

You can extend Ember components further by customizing their wrapping [tag or
class
names](http://emberjs.com/guides/components/customizing-a-components-element/).
You can even [wrap
content](http://emberjs.com/guides/components/wrapping-content-in-a-component/)
in a component, which is useful for things like dropdowns or accordions.

Read the [Ember 2.0 Road map](https://github.com/emberjs/rfcs/pull/15) to see
what’s coming next. We have some fun new toys to look forward to, like a new
HTMLBars syntax.

```handlebars
{{user-avatar url=user.avatarURL}}
```

will change to:

```html
<user-avatar url={{user.avatarURL}}>
```

Read [Ember’s guides](http://emberjs.com/guides/components/) for a closer
look of current implementation. They’re fantastic.
