Skip to content

🖼️ Using the icon Property

NOTE

Available from lovelace-material-components version 1.7.0

🌟 Overview

The icon property is highly flexible and supports three usage modes across multiple Google cards:

🔹 Available for:

🆓 Free Version

  • material-control-card
  • material-button-card
  • material-slider-card
  • material-climate-card

✨ Pro - Ultimate Version

NOTE

All the card has the support of this.

🔹 1. Static Icon

You can define a fixed icon, independent of the entity state:

yaml
type: custom:material-control-card
name: Lamp
entity: switch.lamp
icon: mdi:lightbulb

In this case, the icon will never change.

🔹 2. Dynamic Icon with stateObj

You can dynamically change the icon based on the entity state, using the [[[ ... ]]] JavaScript template syntax.

Inside the template you have access to:

  • entity → the full entity object
  • entity.state → the current state
  • hass → the global Home Assistant object (services, entities, attributes, etc.)

Example — Climate Control

yaml
type: custom:material-control-card
name: Heating
entity: climate.heating
icon: |
  [[[ 
    switch (entity.state) {
      case 'off': return 'm3s:thermometer';
      case 'heat': return 'mdi:fire';
      case 'cool': return 'mdi:mode-cool';
      case 'dry': return 'mdi:cool-to-dry';
      case 'heat_cool': return 'mdi:thermostat-auto';
      case 'auto': return 'mdi:auto-download';
      default: return 'mdi:thermometer';
    }
  ]]]

👉 In this example, the icon changes automatically depending on the state (off, heat, cool, etc.).

🔹 3. Dynamic Icon with Attributes

You can also use entity attributes when choosing an icon:

yaml
icon: |
  [[[ 
    return entity.attributes.battery_level > 20 
      ? 'mdi:battery' 
      : 'mdi:battery-alert';
  ]]]

⚠️ Important Notes

  • Always use proper YAML indentation. Use | for multiline templates.
  • If indentation is incorrect, you may get YAML errors like "bad indentation of a mapping entry".
  • Always return a valid icon string (mdi:..., m3s:..., etc.).
  • If you want to use just state instead of entity.state, make sure the underlying TypeScript function has been updated to provide it.

✅ Summary

  • icon: mdi:lamp → static
  • icon: | [[[ switch(entity.state) {...} ]]] → dynamic by state
  • icon: | [[[ return entity.attributes.xxx ]]] → dynamic by attributes