Lovelace: Button card

You need to define your grid with something like or at least if how i’ll do it. i.m not an expert i’m still learning. i supossed is like your line: layout: icon_name_state

        styles:
          grid:
            - grid-template-areas: '"i name"'
            - grid-template-columns: min-content min-content
            - grid-template-rows: min-content

and them the style like:

    name:
      - justify-self: start

Played a little bit … it worked like this:

        layout: icon_name_state2nd
        size: 100%
        styles:
          grid:
            - grid-template-columns: 20% min-content
          card:
            - width: 150px
            - padding: 7px

image

Thanks @d13g0m0nt3s for your quick prompt!!

@Ildar_Gabdullin the ‘-20px’ margin-left shifts left the name, but unfortunately it remains cut on the right, even if there is still some space on right of the card.
Thanks anyway for your quick prompt too!!

1 Like

Hello everyone!

I’m migrating my mushroom cards to button-card to achieve a faster loading dashboard. When using stack in card extensively, the loading becomes slow…

I created a stack of buttons, and one of them is supposed to toggle the side menu bar, but I’m getting an error with this code:

  bnt_3:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          [[[
            this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
            return none;
          ]]]

error:

ButtonCardJSTemplateError: ReferenceError: none is not defined in 'this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true})); return none...'

If the button is a single one it works:

type: custom:button-card
icon: mdi:menu
tap_action:
  action: call-service
  service: |-
    [[[
      this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
      return none;
    ]]]

what reason do you have to suppose that custom:button-card would be faster than custom:mushroom-card?

do we have any benchmark numbers on that?

image

Unfortunately, I no longer have the old card, but it was a combination of:
stack-in-card
vertical-stack
horizontal-stack
layout-card
mushroom-chips-card
mushroom-template-card
card-mod

And now, I only use:
button-card
vertical-stack
conditional
card-mod

When I open the Home Assistant application on my smartphone, I notice that the button-card cards are the first to appear. The other cards have a longer loading time, and I think it’s because of card-mod.

exactly how? vertical/horizontal/grid?

I copied your code and did:

type: vertical-stack
cards:
  - type: custom:button-card
    icon: mdi:menu
    tap_action:
      action: call-service
      service: |-
        [[[
          this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
          return none;
          ]]]
  - type: custom:button-card
    icon: mdi:menu
    tap_action:
      action: call-service
      service: |-
        [[[
          this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
          return none;
          ]]]
  - type: custom:button-card
    icon: mdi:menu
    tap_action:
      action: call-service
      service: |-
        [[[
          this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
          return none;
          ]]]

and it works on all 3 buttons

By doing it this way, I know it works. My concern is if I use it this way:

type: custom:button-card
styles:
  grid:
    - grid-template-columns: auto
    - grid-template-areas: |
        "bnt_1 bnt_2"
custom_fields:
  bnt_1:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          [[[
           this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
           return none;
          ]]]
  bnt_2:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          [[[
           this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}));
           return none;
          ]]]

Is it a return issue?

Error states none is not defined in

added bubbles1 and bubbles2 for testing

type: custom:button-card
styles:
  grid:
    - grid-template-columns: auto
    - grid-template-areas: |
        "bnt_1 bnt_2"
custom_fields:
  bnt_1:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          [[[
            this.dispatchEvent(new Event('hass-toggle-menu', { bubbles1: true, composed: true}));
            return null; ]]]
  bnt_2:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          [[[
           this.dispatchEvent(new Event('hass-toggle-menu', { bubbles2: true, composed: true}));
           return null;  ]]]        

That way not work, I can’t toggle the menu button.

I added the quotes around none to show that is was possibly the issue or the bracketing.

Does removing the inner brackets toggle the menu button?

type: custom:button-card
styles:
  grid:
    - grid-template-columns: auto
    - grid-template-areas: |
        "bnt_1 bnt_2"
custom_fields:
  bnt_1:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          [[[
            this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}))
            return none; 
  bnt_2:
    card:
      type: custom:button-card
      icon: mdi:menu
      tap_action:
        action: call-service
        service: |-
          
           this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true}))
           return none;  ]]]     

return null doesn’t cause the error with original bracketing, but states no service to run.

Removing the inner brackets i get this error:

Service [[[ this.dispatchevent(new event('hass-toggle-menu', { bubbles1: true, composed: true})) return none; called service [[[ this.dispatchEvent(new Event('hass-toggle-menu', { bubbles1: true, composed: true})) return none; which was not found.

I’m trying with this code, but if there’s another way to toggle the menu button with button-card, let me know.

It appears the button card does not like to execute the services when nested. I wanted to test how it was grouping the buttons and didn’t expect positive results without renaming bubbles1 back to bubbles.

I have zero experience with using a button in a button, or with the service at hand. However, could it have to do with the ‘path’ to the actionable item?

As if somehow the nested button doesnt get out of the main button to the menu item, and has no item to perform the action on, hence ending up logging none?

I suppose this would be an issue to post on the Button-card repo, as it is not yet provided for, and it would seem a nice addition to the power of button-card

For the time being, I’d suggest to use any of the other available options, and redesign your card to the options that do work… :wink:

I think I finally managed to do it. I had to use helpers and automations to achieve it.

image

HELPERS

input_boolean.button_menu
input_boolean.button_back
input_boolean.button_forward

AUTOMATION

alias: Buttons State OFF
trigger:
  - platform: state
    entity_id:
      - input_boolean.button_menu
    to: "on"
    for:
      seconds: 1
  - platform: state
    entity_id:
      - input_boolean.button_back
    to: "on"
    for:
      seconds: 1
  - platform: state
    entity_id:
      - input_boolean.button_forward
    to: "on"
    for:
      seconds: 1
action:
  - service: input_boolean.turn_off
    target:
      entity_id: input_boolean.button_menu
    data: {}
  - service: input_boolean.turn_off
    target:
      entity_id: input_boolean.button_back
    data: {}
  - service: input_boolean.turn_off
    target:
      entity_id: input_boolean.button_forward
    data: {}
mode: single

CHIP BUTTONS

type: custom:button-card
styles:
  card:
    - padding: 0px 0px 0px 0px
    - box-shadow: none
    - background: none
    - border: 0
  grid:
    - grid-template-columns: auto
    - grid-template-areas: |
        "bnt_1 bnt_2 bnt_3"
  custom_fields:
    bnt_1:
      - justify-self: center
    bnt_2:
      - justify-self: center
    bnt_3:
      - justify-self: center
custom_fields:
  bnt_1:
    card:
      type: custom:button-card
      entity: input_boolean.button_menu
      icon: mdi:menu
      show_name: false
      tap_action:
        action: toggle
      variables:
        menu: |-
          [[[
           if (states['input_boolean.button_menu'].state === 'on') {
             this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true }));
           }
          ]]]
      styles:
        icon:
          - width: 20px
          - color: white
        card:
          - border-radius: 100px
          - width: 39px
          - height: 39px
          - background: rgb(39,39,39)
          - box-shadow: none
  bnt_2:
    card:
      type: custom:button-card
      entity: input_boolean.button_back
      icon: mdi:arrow-left
      show_name: false
      tap_action:
        action: toggle
      variables:
        back: |-
          [[[
           if (states['input_boolean.button_back'].state === 'on') {
             history.back();
           }
          ]]]
      styles:
        icon:
          - width: 20px
          - color: white
        card:
          - border-radius: 100px
          - width: 39px
          - height: 39px
          - background: rgb(39,39,39)
          - box-shadow: none
  bnt_3:
    card:
      type: custom:button-card
      entity: input_boolean.button_forward
      icon: mdi:arrow-right
      show_name: false
      tap_action:
        action: toggle
      variables:
        forward: |-
          [[[
           if (states['input_boolean.button_forward'].state === 'on') {
             history.forward();
           }
          ]]]
      styles:
        icon:
          - width: 20px
          - color: white
        card:
          - border-radius: 100px
          - width: 39px
          - height: 39px
          - background: rgb(39,39,39)
          - box-shadow: none
1 Like

let me see if my former forward and back buttons did something alike:

     - type: custom:button-card
       template: button_shortcut_menu
       tooltip: Back
       icon: mdi:arrow-left
       show_name: false
       tap_action:
         action: toggle
       entity: input_boolean.back_button
       variables:
         back: |
           [[[
            if (entity.state == 'on') {history.back() ;}
           ]]]


     - type: custom:button-card
       template: button_shortcut_menu
       tooltip: Forward
       icon: mdi:arrow-right
       show_name: false
       tap_action:
         action: toggle
       entity: input_boolean.forward_button
       variables:
         next: |
           [[[
            if (entity.state == 'on') {history.forward() ;}
           ]]]

and I used these automations there:

automation:

# needed for Javascript in buttons shortcut menu
  - alias: Back button
    id: back_button
    mode: single
    trigger:
      platform: state
      entity_id: input_boolean.back_button
      to: 'on'
    action:
      service: input_boolean.turn_off
      target:
        entity_id: input_boolean.back_button

  - alias: Forward button
    id: forward_button
    mode: single
    trigger:
      platform: state
      entity_id: input_boolean.forward_button
      to: 'on'
    action:
      service: input_boolean.turn_off
      target:
        entity_id: input_boolean.forward_button

somehow that seems much simpler, but I need to check if the results is the same… :wink:

seems awfully indentical if you ask me… I do remember though it wasnt reliable, and in the end did away with them. I just had to find them in my 2022 backups .
Admit I didnt have the menu item button, and that service is new to me.

Do you have some documentation where you got that from?

I have experienced this in the past (here) when using a button is inside a button. Using another type of card inside the button card worked for me in the past, but I like your resolution. Nice workaround!

The solution of the helper buttons with automations was something you had shared in the past, and I took the menu code from here:

https://gist.github.com/vlaraort/b74d6c3113f1a031245d27329e1f22f7

1 Like

Right now I’m facing another difficulty, perhaps simpler than the previous one, but I’m having trouble solving it…

I want to have two font sizes and have them centered in the middle of the card.

imageimage

type: custom:button-card
icon: mdi:home-thermometer
entity: sensor.temperatura_media_casa
show_entity_picture: true
show_name: false
show_state: true
tap_action:
  action: more-info
styles:
  icon:
    - width: 22px
    - color: |-
        [[[
          var state = states['sensor.temperatura_media_casa'].state;
          if (state <= 18) {
            return 'rgb(100,149,237)'; //blue
          } else if (state <= 24) {
            return 'rgb(244,208,63)'; //yellow
          } else {
            return 'rgb(231,76,60)'; //red
          }
        ]]]
  img_cell:
    - background: |-
        [[[
          var state = states['sensor.temperatura_media_casa'].state;
          if (state <= 18) {
            return 'rgba(100,149,237,0.2)'; //blue_t
          } else if (state <= 24) {
            return 'rgba(244,208,63,0.2)'; //yellow_t
          } else {
            return 'rgba(231,76,60,0.2)'; //red_t
          }
        ]]]
    - border-radius: 100%
    - width: 30px
    - height: 30px
  state:
    - font-size: 14px
    - font-weight: 500
  card:
    - border-radius: 100px
    - width: 100%
    - height: 39px
    - background: rgb(39,39,39)
    - box-shadow: none
    - padding: 0px 10px 0px 5px
  grid:
    - grid-template-columns: min-content 1fr
    - grid-template-areas: |
        "i s"
    - gap: 0px 10px;

That is a tough one. They are grouped together.

image

i have tested using label and name with template but not figure out how to center the data