Show two-color icon where color changes with state

What is the best way to use two-color / multi-color icons that can change their color with state?

two-color-icon-state two-color-icon-state2

I have managed to create the example above using button-card and a custom_field instead of the real icon, so that I can use <svg> code with Javascript for the state change. But is this really the best approach possible?

1 Like

Can you post how you actually accomplished this? Trying to do something similar.

It’s a pain.

I used templates with GitHub - custom-cards/button-card: ❇️ Lovelace button-card for home assistant

The icon is actually composed of two SVG paths set manually. These are not icons from the icon picker. I use the following set of templates (example for the “Deckenlampe” from above):

button_card_templates:
  activated_state:
    state:
      - id: activated_state
        styles:
          card:
            - background-color: var(--primary-text-color)
            - color: var(--card-background-color)
          name:
            - color: var(--accent-color)
            - font-weight: bold
          label:
            - color: var(--accent-color)
          state:
            - color: var(--accent-color)
          icon:
            - color: var(--accent-color)
  raw_buttons:
    template: activated_state
    color: var(--paper-item-icon-color)
    tap_action:
      action: toggle
      haptic: medium
    state:
      - value: 'on'
        id: activated_state
    styles:
      card:
        - '--mdc-ripple-color': black
        - '--mdc-press-opacity': 0.5
        - font-size: var(--paper-font-body1_-_font-size)
        - padding-bottom: 10px
  square_raw_buttons:
    template: raw_buttons
    aspect_ratio: 1/1
  buttons:
    template: square_raw_buttons
    show_name: true
    show_label: true
    show_state: false
    color_type: icon
    styles:
      grid:
        - grid-template-areas: '"i" "l" "n"'
        - grid-template-columns: 1fr
        - grid-template-rows: 4fr 1fr 1fr
      img_cell:
        - align-self: start
        - text-align: start
        - justify-content: start
        - padding-left: 16px
      name:
        - justify-self: start
        - padding-left: 10px
        - font-weight: bold
        - max-width: 80%
      label:
        - justify-self: start
        - padding-left: 10px
  state_buttons:
    template: buttons
    show_name: false
    show_state: true
    styles:
      grid:
        - grid-template-areas: '"i" "l" "s"'
      state:
        - justify-self: start
        - padding-left: 10px
        - font-weight: bold
  two_color_settings:
    show_icon: false
    styles:
      custom_fields:
        icon_color:
          - justify-self: start
          - left: 5%
          - top: 10%
          - width: 46%
          - position: absolute
  two_color_ceiling:
    template: two_color_settings
    custom_fields:
      icon_color: |
        [[[
          const color_light     = "var(--mmp-accent-color, var(--accent-color))";
          const color_dark      = "var(--paper-item-icon-color)";
          const color_darkshell = "var(--disabled-text-color)";

          const shell = entity.state === "off" ? color_dark : color_darkshell;
          const light = entity.state === "off" ? color_dark : color_light;

          return `
          <svg viewBox="0 0 24 24">
            <path d="m8 4v2h8v-2h-8zm-4.0488 3a2 2 0 0 0-1.9512 2v3a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2h-16a2 2 0 0 0-0.048828 0z" fill="${shell}"/>
            <path d="m21.987 9h-19.983c0.017425 1.1153-0.037128 2.2348 0.031703 3.3472 0.15851 1.0313 1.2009 1.7536 2.2206 1.6413 5.2837-0.0024 10.567 0.0047 15.851-0.0035 1.1319-0.03437 2.0102-1.1421 1.8795-2.2456v-2.7394z" fill="${light}"/>
          </svg>`
        ]]]

This goes to the top of the RAW configuration editor in your dashboard.

The code for the actual lamp switch is very easy then:

type: custom:button-card
template: light_ceiling
entity: light.study_deckenlampe
name: Deckenlampe

Make sure you read up on the usage of templating for custom:button-card or you won’t be able to reproduce this.