Lovelace: Button card

Try removing any other icon declarations. Try this:

    icon: >
      [[[ return `<ha-icon icon='${entity.attributes.icon}' title='${variables.path.replace('_',' ').toUppercase()}'></ha-icon>` ]]]

my buttons don’t have an entity… so I cant use entity.attributes.icon I am afraid. Hence the icon declaration in my current buttons.

maybe use the

[[[ return<ha-icon icon='mdi:light-switch' title=’${variables.path.replace(’_’,’ ‘).toUppercase()}’></ha-icon> ]]]

What about

    variables:
      path: lights
      icon: mdi:light-switch
    icon: >
      [[[ return `<ha-icon icon='${variables.icon}' title='${variables.path.replace('_',' ').toUppercase()}'></ha-icon>` ]]]

I have the following template for a transparent label card and it works fine for most the groups except for lights. When one of the entities in the group turns on, then the label fades out. This happens only on light theme backgrounds. How do I fix this?

transparent_header_card:
  color_type: label-card
  color: transparent
  show_icon: false
  styles:
    card:
      - background-color: transparent
      - box-shadow: none
    name:
      - font-size: 20px
      - text-align: center
      - letter-spacing: '-0.01em'
      - font-weight: bold
              - type: 'custom:button-card'
                template: transparent_header_card
                name: Lights
                entity: group.lights
                tap_action:
                  action: toggle
                confirmation:
                  text: '[[[ return `Are you sure you want to turn on or off all ${entity.attributes.friendly_name}?` ]]]'

Screen Shot 2020-09-12 at 1.15.03 PM Screen Shot 2020-09-12 at 1.15.12 PM

1 Like

Hi Petro,

thank you for help!

i copy an paste your Code with my entities:

type: picture-elements
image: /local/images/transparent_1to1.png
style: |
  ha-card { 
    border-radius: 15px;
  }
elements:
- type: custom:mini-graph-card
  style:
    top: 40%
    left: 50%
    width: 100%
    height: 80%
    translate: translate(-50%, -50%)
    '--paper-card-background-color': 'rgba(0, 0, 0, 0.0)'
    '--ha-card-background': "rgba(0, 0, 0, 0.0)"
    '--ha-card-box-shadow': 'none'
    z-index: 3
    pointer-events: none
  entities:
    - sensor.owm_temperature
  group: true
  points_per_hour: 1
  hour24: true
  line_color: var(--paper-item-icon-active-color)
  line_width: 10
  hours_to_show: 24
  update_interval: 600
  show:
    name: false
    icon: false
    state: false
    points: false
    legend: false
    average: false
    extrema: false
    labels: false
    fill: false
    labels_secondary: false
    name_adaptive_color: false
    icon_adaptive_color: false
- type: custom:button-card
  style:
    top: 50%
    left: 50%
    width: 100%
    translate: translate(-50%, -50%)
  aspect_ratio: 1/1
  entity: sensor.owm_temperature
  color: var(--paper-item-icon-color)
  show_name: true
  show_label: true
  show_icon: true
  show_last_changed: true
  size: 70%
  tap_action:
    action: more-info
    haptic: light
  styles:
    icon:
    - opacity: 0.3
    - width: 100%
    img_cell:
    - top: 0%
    - left: 30%
    - position: absolute
    - z-index: 2
    grid:
    - grid-template-areas: '"info info" "n n" "l l"'
    - grid-template-columns: 40% 1fr
    - grid-template-rows: 1fr min-content min-content
    - position: relative
    card:
    - padding: 10px
    - z-index: 1
    name:
    - justify-self: start
    - align-self: end
    - font-weight: bold
    - font-family: Helvetica 
    - font-size: 12px
    - text-align: start
    - background-image: linear-gradient(to right, white 0%, white 80%, rgba(0,0,0,0))
    - -webkit-background-clip: text
    - -webkit-text-fill-color: transparent
    - position: relative
    - display: inline-block
    - width: 100%
    - align-content: start
    - text-align: start
    - text-overflow: unset
    - z-index: 5
    label:
    - justify-self: start
    - align-self: end
    - font-weight: bold
    - font-family: Helvetica 
    - font-size: 12px
    - text-align: start
    - background-image: linear-gradient(to right, var(--paper-item-icon-color) 0%, var(--paper-item-icon-color) 80%, rgba(0,0,0,0))
    - -webkit-background-clip: text
    - -webkit-text-fill-color: transparent
    - position: relative
    - display: inline-block
    - width: 100%
    - align-content: start
    - text-align: start
    - text-overflow: unset
    - z-index: 5
    custom_fields:
      info:
      - align-self: start
      - width: 40%
      - z-index: 5
  custom_fields:
    info: >
      [[[
        var entity_id = (entity === undefined) ? 'Invalid Entity' : entity.entity_id;
        var statestr = (entity === undefined || entity.state === undefined) ? null : entity.state;
        var units = (statestr && entity.attributes.unit_of_measurement) ? entity.attributes.unit_of_measurement : null;
        var date = (statestr && entity.attributes.device_class === 'timestamp') ? new Date(statestr) : null;
        var value;
        if (statestr && date === null) {
          if (statestr.split('.').length - 1 <= 1){
            var test = parseFloat(parseFloat(statestr).toFixed(2));
            value = (isNaN(test)) ? null : test;
            // test if units are in the state because some sensors are stupid.  Looking
            //   at you synology.
            const expr = /[^-.0-9]+/;
            var has_units = expr.test(statestr.trim());
            // console.log(`${entity_id}: "${statestr}" ${matches}`);
            if (value && has_units)
              units = statestr.replace(/[.0-9]+/, ''); 
          }
        }
        // console.log(`${entity_id}: ${statestr}, ${units}, ${date}, ${value}`);
        const length = 50;
        const width = 3;
        var radius = length / 2;
        if (date){
          let now = new Date();
          var tdelta = Math.floor((now - date)/1000);
          // console.log(`${entity_id}: ${tdelta}`);
          function plural(descriptor, divisor){
            var ret = Math.floor(tdelta/divisor);
            return (ret == 1) ? [ret, descriptor] : [ret, `${descriptor}s`];
          }
          var values;
          if (tdelta < 60)
            values = plural('second', 1);
          else if (tdelta < 60 * 60)
            values = plural('minute', 60);
          else if (tdelta < 60 * 60 * 24)
            values = plural('hour', 60 * 60);
          else if (tdelta < 7 * 60 * 60 * 24)
            values = plural('day', 60 * 60 * 24);
          else
            values = plural('week', 7 * 60 * 60 * 24);
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="43%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${values[0]}<tspan x="50%" dy="1.2em" font-size="10" font-weight="normal" >${values[1]}</tspan>
              </text>
            </svg>
            `;
        }
        else if (value && units && units === '%') {
          radius = (length - 3) / 2;
          const circumference = radius * 2 * Math.PI;
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="none" stroke="var(--paper-item-icon-color)" opacity="0.5" stroke-width="${width}" />
              <circle style="
                  transform: rotate(-90deg);
                  transform-origin: 50% 50%;
                  stroke-dasharray: ${circumference};
                  stroke-dashoffset: ${circumference - value / 100 * circumference};
                "
                id="c_brightness" cx="25" cy="25" r="${radius}" stroke="var(--paper-item-icon-active-color)" stroke-width="${width}" fill="none" stroke-linecap="round" />
              <text x="50%" y="54%" fill="var(--primary-text-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan font-size="10" font-weight="normal" >%</tspan>
              </text>
            </svg>
            `;
          }
        else if (value && units && units.includes('°')) {
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="54%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan font-size="10" font-weight="normal" >${units}</tspan>
              </text>
            </svg>
            `;
        }
        else if (value && units && units.length > 1) {
          var y = (String(value).length > units.length) ? "50%" : "43%";
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="${y}" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan x="50%" dy="1.2em" font-size="10" font-weight="normal" >${units}</tspan>
              </text>
            </svg>
            `;
          }
        else if (value) {
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="54%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan font-size="10" font-weight="normal" >${units}</tspan>
              </text>
            </svg>
            `;
        }
        return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="54%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${statestr}
              </text>
            </svg>
            `; 
      ]]]

but it doesn’t show me anything and I have no error in the log or anything.

nope, sorry. as long as I use the icon: field, no icon is displayed using the templates we tried.


I can use the name field and have the icon displayed, but then it appears is an incorrect format:

also, it doesnt like the template, so above I took that out for testing purposes, trying to take it one step at a time…

button-card.js?v=3.3.6:1643 ButtonCardJSTemplateError: TypeError: variables.path.replace(...).toUppercase is not a function in 'return `<ha-icon icon='mdi:light-switch' title='${variables.path.replace('_',' ').toUppercase()}'>...

all in all, it seems this is either not possible, or we need the hand of the author to make it possible. Hope Rom is having a look anytime soon…

I guess, what would be easiest is a dedicated tooltip variable, set that in the button_card template as follows:

button_shortcut_menu:
  variables:
    dashboard: >
      [[[ return window.location.pathname.split('/')[1] ]]]
    view: >
      [[[ return window.location.pathname.split('/').slice(-1) ]]]
  size: 25px
  styles:
    icon:
      - color: var(--secondary-text-color)
# add a new styles field for the tooltip here
      - tooltip: >
          [[[ return variables.tooltip ]]]
    card:
      - box-shadow: none
      - background: >
          [[[ return variables.view == variables.path
              ? 'var(--secondary-background-color)' : 'var(--card-background-color)';
          ]]]
  extra_styles: |
    /* Tooltip container */
    .tooltip {
      position: relative;
      display: inline-block;
      border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
    }

    /* Tooltip text */
    .tooltip .tooltiptext {
      visibility: hidden;
      width: 120px;
      background-color: black;
      color: red;
      text-align: center;
      padding: 5px 0;
      border-radius: 6px;

      /* Position the tooltip text - see examples below! */
      position: absolute;
      z-index: 1;
    }

    /* Show the tooltip text when you mouse over the tooltip container */
    .tooltip:hover .tooltiptext {
      visibility: visible;
    }

and then set the button card config like:

  - type: custom:button-card
    template: button_shortcut_menu
    icon: mdi:light-switch
    variables:
      path: lights
      tooltip: Light panel  # <----
    tap_action:
      action: navigate
      navigation_path: /lovelace/lights
    styles:
      icon:
        - color: >
            [[[
              return (states['group.all_inside_lights'].state == 'on')
              ? 'gold': 'grey';
            ]]]

for now I’m forced to go back to my tooltip-less shortcut menu bar :wink:

Capitialization:

    variables:
      path: lights
      icon: mdi:light-switch
    icon: >
      [[[ return `<ha-icon icon='${variables.icon}' title='${variables.path.replace('_',' ').toUpperCase()}'></ha-icon>` ]]]

toUppercase toUpperCase

Is there anyway I can get a camera view to take up the whole of the button space please? No matter what I do, I get a small snapshot in a larger button

type: 'custom:button-card'
entity: camera.front_door
show_entity_picture: 'true'
styles:
  card:
    - height: 300px

Nicely spotted. thanks.

doesnt work though, no icon using the icon field… (error has gone , so that’s good :wink: )

have a look:

button-card-template:

button_shortcut_menu:
  variables:
    dashboard: >
      [[[ return window.location.pathname.split('/')[1] ]]]
    view: >
      [[[ return window.location.pathname.split('/').slice(-1) ]]]
  size: 25px
  icon: >
    [[[ return `<ha-icon icon='${variables.icon}' title='${variables.path.replace('_',' ').toUpperCase()}'></ha-icon>` ]]]
  styles:
    icon:
      - color: var(--secondary-text-color)
    card:
      - box-shadow: none
      - background: >
          [[[ return variables.view == variables.path
              ? 'var(--secondary-background-color)' : 'var(--card-background-color)';
          ]]]
  extra_styles: |
    /* Tooltip container */
    .tooltip {
      position: relative;
      display: inline-block;
      border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
    }

    /* Tooltip text */
    .tooltip .tooltiptext {
      visibility: hidden;
      width: 120px;
      background-color: black;
      color: red;
      text-align: center;
      padding: 5px 0;
      border-radius: 6px;

      /* Position the tooltip text - see examples below! */
      position: absolute;
      z-index: 1;
    }

    /* Show the tooltip text when you mouse over the tooltip container */
    .tooltip:hover .tooltiptext {
      visibility: visible;
    }

and buttons like:

  - type: custom:button-card
    template: button_shortcut_menu
    variables:
      path: home
      icon: mdi:home
    tap_action:
      action: navigate
      navigation_path: /lovelace/home
    styles:
      icon:
        - color: >
            [[[
              return (states['sensor.count_alerts_notifying'].state > 0)
              ? 'red': 'green';
            ]]]
    state:
      - operator: template
        value: >
          [[[ return (states['sensor.count_alerts_notifying'].state > 0) ]]]
        spin: true

  - type: custom:button-card
    template: button_shortcut_menu
#    icon: mdi:light-switch
    variables:
      path: lights
      icon: mdi:light-switch
    tap_action:
      action: navigate
      navigation_path: /lovelace/lights
    styles:
      icon:
        - color: >
            [[[
              return (states['group.all_inside_lights'].state == 'on')
              ? 'gold': 'grey';
            ]]]

this works ok for the icon to show

  icon: >
    [[[ return variables.icon ]]]

though somehow my background color gets killed…

type: 'custom:button-card'
entity: camera.front_door
show_entity_picture: 'true'
styles:
  card:
    - height: 300px
size: 100%

should work I think

1 Like

perfect thank you… it was that simple :smiley:

Any idea how often the thumbnail refreshes please?

First of all, completely remove the extra_styles. You don’t have to, but you should.
I think it might be that the way that button-card renders the icons ha-icon won’t work. We’ll see what happens…

Probably as often as the entity_picture refreshes and button-card bothers to check…

separate post for separate issue:

before, this worked perfectly:

      - background: >
          [[[ return variables.view == variables.path
              ? 'var(--secondary-background-color)' : 'var(--card-background-color)';
          ]]]

coloring the background of the button if the path was identical the Lovelace view. Right now, I see it coloring when clicking the button but then it fades out to the regular color

update

this is fixed:
somehow I think I deleted the

keep:
  background: true

on the stack-in-card, but most of all, I reordered the variables in the button-card config, and moved them to the top. Noticed before this is of influence to the card, and now, where reading/declaring variables both in the button-card-template and button-card config itself, this seems very important.

One down, one to go (tooltips…)

I will test that (have done before) but remember I needed those for the tooltip…?
without extra styles no tooltip will be created? This issue started with trying to create the tooltip, not with the icon, which worked perfectly.

Hi, is there any example of putting a background image into this button-car?

I want to try to replace a " Picture Elements Card Configuration" which a background and some icons on it…

styles:
  card:
    - background: purple

Was this for me?

Is it possible to fill the entire button card with the entity_picture? Right now I’m getting borders with button card. The entity_picture is nice and centered, but I want it to fill the entire button cards.

I have some ideas to use button card as a media player card (like mini media player). But I want it to fill the entire card with the entity picture.