Lovelace: Button card

@RomRider, looks great. Ive been working on my UI trying to use this card where possible as its super versatile. I need to investigate the media player side of things as that looks good.

It would also be interesting to know how you are handling the YAML for popups. Do you use YAML mode or the UI Editors?

I wanted to setup separate files for each popup but i don’t want to loose the UI editor and switch to YAML only mode so for now i am just pointing out to a separate dashboard that contains a view to each room.

Example below of one of those views with my button card which is basically two button cards together (1 power toggle and 1 main card for more-info with a built in slider and custom SVG hue bulb icons)

3 Likes

I don’t like UI’s to configure stuff… I’m probably old school :stuck_out_tongue: So I use only yaml… I’m kind of sad now that some of the integrations are only possible to configure with the UI :confused:

I have one separate file for each popup, but they all call a decluttering-card template that embeds everything

I had that in place before with my old shitty and ugly UI, but I found it to be not very ergonomic (especially the fact that you had to go “back” with a button / swipe back to the first page every time)

What’s the progress bar called in css? The % around your brightness.

Edit: can you also post how you got the shadow on the icon itself?

That a piece of svg I’ve copied over from @Mattias_Persson.
Here’s the code:

  custom_fields:
    info: >
      [[[
        if (entity.state === 'on' && entity.attributes.brightness) {
          const radius = 20.5;
          const brightness = Math.round(entity.attributes.brightness / 2.54);
          const circumference = radius * 2 * Math.PI; 
          return `
            <svg viewBox="0 0 50 50">
              <circle style="
                  transform: rotate(-90deg);
                  transform-origin: 50% 50%;
                  stroke-dasharray: ${circumference};
                  stroke-dashoffset: ${circumference - brightness / 100 * circumference};
                "
                id="c_brightness" cx="25" cy="25" r="20.5" stroke="var(--sq-info-color)" stroke-width="1.5" fill="none" />
              <text x="50%" y="54%" fill="var(--sq-info-color)" font-size="14" text-anchor="middle" alignment-baseline="middle">${brightness}<tspan font-size="10">%</tspan>
              </text>
            </svg>
          `;
        }
      ]]]

Edit: Adding the shadow for the icon is quite simple:

  state:
    - id: id_on
      styles:
        icon:
          - filter: |
              [[[
                if (entity.attributes.supported_features >> 4 & 1) return "drop-shadow(0px 0px 1px rgba(0,0,0,1))";
              ]]]
2 Likes

I tried every attribute on an icon in the past accept filter. Well now I know, thanks.

Instead of ... when the text is overflowing the card, what I did lately is a nice fade effect:
image

using this css:

      - 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
7 Likes

Awesome. How did you get that Sonos popup???

It is 4 button cards to select the master, then a state-switch with mini-media-player to display the Sonos grouping list, then 4 mini-media-player for the volume bars

i dont understand how its in a pop up, would you mind sharing the code?

the browser_mod part i suspect…

Yes, it’s with browser_mod:

action: call-service
service: browser_mod.popup
service_data:
  title: Sonos Groups
  deviceID:
    - this
  style:
    border-radius: 10px
    overflow: hidden
    background: var(--lovelace-background, var(--primary-background-color))
  card:
    type: custom:decluttering-card
    template: square_sonos_group_manage #which is a vertical-stack with everything inside

And then the decluttering-template:

square_sonos_group_manage:
  variables:
    - sonos_master: 
  card:
    type: vertical-stack
    cards:
      - type: horizontal-stack
        cards:
          - type: custom:button-card
            template: square_mini_media_player
            entity: media_player.sonos_universal
            variables:
              name: 'Living Room'
              default_background: /local/sonos_connect_big.png
              sonos_master: media_player.sonos_connect
          - type: custom:button-card
            template: square_mini_media_player
            entity: media_player.sonos_office_stereo
            variables:
              name: 'Office'
              default_background: /local/sonos_one_big.png
          - type: custom:button-card
            template: square_mini_media_player
            entity: media_player.sonos_bedroom_stereo
            variables:
              name: 'Bedroom'
              default_background: /local/sonos_one_big.png
              sonos_master: media_player.sonos_bedroom_stereo
          - type: custom:button-card
            template: square_mini_media_player
            entity: media_player.sonos_bathroom
            variables:
              name: 'Bathroom'
              default_background: /local/sonos_one_big.png
      - type: entities
        style: |
          ha-card {
            --mini-media-player-base-color: var(--paper-item-icon-color);
          }
        entities:
          - type: custom:mini-media-player
            style:
              .: |
                :host {
                  --mmp-text-color: var(--paper-item-icon-color);
                  --mini-media-player-accent-color: var(--paper-item-icon-active-color)
                }
              ha-card: |
                  .entity__info__name {
                    font-weight: bold !important;
                    text-transform: lowercase;
                  }
                  .entity__info__media {
                    color: var(--paper-item-icon-color) !important;
                  }
            entity: '[[sonos_master]]'
            group: true
            hide:
              power: true
              icon: true
              source: true
              volume: true
              progress: true

            speaker_group:
              platform: sonos
              show_group_count: true
              expanded: true
              entities:
                - entity_id: media_player.sonos_connect
                  name: Living Room
                - entity_id: media_player.sonos_office_stereo
                  name: Office
                - entity_id: media_player.sonos_bedroom_stereo
                  name: Bedroom
                - entity_id: media_player.sonos_bathroom
                  name: Bathroom
          - type: divider
            style:
          - type: custom:mini-media-player
            entity: media_player.sonos_universal
            group: true
            name: Living Room
            hide:
              controls: true
              progress: true
              info: true
              icon: true
              source: true
          - type: custom:mini-media-player
            entity: media_player.sonos_office_stereo
            name: Office
            group: true
            hide:
              controls: true
              progress: true
              info: true
              icon: true
              source: true
          - type: custom:mini-media-player
            entity: media_player.sonos_bedroom_stereo
            group: true
            name: Bedroom
            hide:
              controls: true
              progress: true
              info: true
              icon: true
              source: true
          - type: custom:mini-media-player
            entity: media_player.sonos_bathroom
            name: Bathroom
            group: true
            hide:
              controls: true
              progress: true
              info: true
              icon: true
              source: true

for some reason I cannot get the circle to render. svg viewbox is causing the problem. Not sure what. What version of your card are you using? I’m on 3.2.3.

EDIT: Everything seems to be calculating properly. No errors in logs and the html looks correct. Chrome is just not rendering it.

      <svg viewBox="0 0 50 50">
        <circle style="
            transform: rotate(-90deg);
            transform-origin: 50% 50%;
            stroke-dasharray: 128.8052987971815;
            stroke-dashoffset: 63.114596410618944;
          "
          id="c_brightness" cx="25" cy="25" r="20.5" stroke="var(--paper-item-icon-active-color)" stroke-width="1.5" fill="none" />
        <text x="50%" y="54%" fill="var(--paper-item-icon-active-color)" font-size="14" text-anchor="middle" alignment-baseline="middle">51<tspan font-size="10">%</tspan>
        </text>
      </svg>

it’s probably rendered but either hidden somewhere because of the styles you apply on the field or because its z-index is not correct and it’s under something else.
If you go in the chrome debugger and unfold the button-card, the element should be there, you’ll see on the page where it is and then you can play with the styles on the div around it.

PS: I’m running 3.3.0-3 (beta), but it shouldn’t change anything for this.

Yeah I’m doing that. I see it. I can’t tell the z order, I would expect a custom field to be on top no?

what are you using for the custom_field style?

It depends on the style of everything else :slight_smile:, my field is info (the circle):

  styles:
    grid:
      - grid-template-areas: '"i info" "n n" "s s" "l l"'
      - grid-template-columns: 1fr 35%
      - grid-template-rows: 1fr min-content min-content min-content
    custom_fields:
      info:
        - align-self: start
        - opacity: 0.5

I’ll try placing it in the grid… I"m using:

    - position: absolute
    - top: 50%
    - right: 50%

Interesting, placing it in the grid works. Might be an issue there? Or how Can i change the Z order with position absolute?

It should also be interesting to note that it doesn’t display if you place it in label field.

svg will scale with its parent container. if you set its position to absolute, you also have to set width and height on the parent container.

1 Like

ah ok always something to learn. When you refer to the container, you mean that I’ll be placing this in the custom field style, correct?

Yes :slight_smile: