---
layout: page
title: "Components"
description: "List of the built-in components of Home Assistant."
date: 2014-12-21 13:35
sidebar: false
comments: false
sharing: true
footer: true
is_homepage: true
hide_github_edit: true
body_id: components-page
regenerate: true
---

{% assign count = site.components | size %}
{% assign nocat = site.components | where: 'ha_category', null | size %}
{% assign tot = count | minus: nocat %}
{% assign components = site.components | sort: 'title' %}
{% assign categories = components | sort: 'ha_category' | map: 'ha_category' | uniq %}
{% capture current_version %}{{ site.current_major_version }}.{{ site.current_minor_version }}{% endcapture %}
{% assign added_one_ago_minor_version = site.current_minor_version|minus: 1 %}
{% capture added_one_ago_version %}{{ site.current_major_version }}.{{ added_one_ago_minor_version }}{% endcapture %}
{% assign added_two_ago_minor_version = site.current_minor_version|minus: 2 %}
{% capture added_two_ago_version %}{{ site.current_major_version }}.{{ added_two_ago_minor_version }}{% endcapture %}
{% assign current_version_components_count = site.components | where: 'ha_release', current_version | size %}
{% assign one_ago_version_components_count = site.components | where: 'ha_release', added_one_ago_version | size %}
{% assign two_ago_version_components_count = site.components | where: 'ha_release', added_two_ago_version | size %}

<p class='note'>
Support for these components is provided by the Home Assistant community.
</p>
<div class="grid">
  <div class="grid__item one-sixth lap-one-whole palm-one-whole">

    <div class="filter-button-group">
      <a href='#all' class="btn">All ({{tot}})</a>
      <a href='#featured' class="btn featured">Featured</a>
      <a href='#added_in_current_version' class="btn added_in_current_version">Added in {{ current_version }} ({{ current_version_components_count }})</a>
      <a href='#added_one_version_ago' class="btn added_one_version_ago">Added in {{ added_one_ago_version }} ({{ one_ago_version_components_count }})</a>
      <a href='#added_two_versions_ago' class="btn added_two_versions_ago">Added in {{ added_two_ago_version }} ({{ two_ago_version_components_count }})</a>

      {% for category in categories %}
        {% if category and category != 'Other' %}
          <a href='#{{ category | slugify }}' class="btn">
            {{ category }}
            ({{ components | where: 'ha_category', category | size }})
          </a>
        {% endif %}
      {% endfor %}

      <a href='#other' class="btn">Other</a>
    </div>
  </div>
  <div class="grid__item five-sixths lap-one-whole palm-one-whole" id="componentContainer">
    {% for component in components %}
      {% if component.ha_category %}
      {% assign sliced_version = component.ha_release | split: '.' %}
      {% assign minor_version = sliced_version[1]|plus: 0 %}
        <a href='{{ component.url }}'
           class='{{ component.ha_category | slugify }}{% if minor_version == site.current_minor_version %} added_in_current_version{% elsif minor_version == added_one_ago_minor_version %} added_one_version_ago{% elsif minor_version == added_two_ago_minor_version %} added_two_versions_ago{% endif %}{% if component.featured %} featured{% endif %}'
           {% unless component.featured %}style='display: none'{% endunless %}>
          <div class='img-container'>
            {% if component.logo %}
              <img src='/images/supported_brands/{{ component.logo }}'>
            {% endif %}
          </div>
          <div class='title'>{{ component.title }}</div>
          <div class='category'>{{ component.ha_category }}</div>
        </a>
      {% endif %}
    {% endfor %}
  </div>
</div>

{% comment %}
## Pages without categories
{% for component in components %}
  {% unless component.ha_category %}
<p>{{ component.title }}</p>
  {% endunless %}
{% endfor %}
{% endcomment %}

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
// undo initial hiding of non-featured cards
if (location.hash !== '') {
  if (location.hash === '#all') {
    jQuery('#componentContainer a').show();
  } else {
    jQuery('#componentContainer .featured').hide();
    jQuery('#componentContainer .' + location.hash.substr(1)).show();
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.2/isotope.pkgd.min.js"></script>
<script>
$(window).load(function(){
  var $container = $('#componentContainer');

  function updateHash(newHash) {
    if ('replaceState' in history) {
      history.replaceState('', '', newHash);
    } else {
      location.hash = newHash;
    }
  }

  function applyFilter() {
    var hash = location.hash;

    var filter;
    if (hash == '') {
      filter = '.featured'
      hash = '#featured'
    } else if (hash == '#all') {
      filter = '*';
    } else {
      filter = '.' + hash.substr(1);
    }

    $('.filter-button-group a.current').removeClass('current');
    $('.filter-button-group a[href='+hash+']').addClass('current');

    $container.isotope({
        filter: filter,
        animationOptions: {
            duration: 750,
            easing: 'linear',
            queue: false
        },
        masonry: {
          columnWidth: 210
        }
     });
  }

  jQuery('.filter-button-group a').click(function() {
    updateHash(this.getAttribute('href'));
    applyFilter();

    return false;
  });

  window.addEventListener('hashchange', applyFilter);

  applyFilter();
});
</script>
