A different take on designing a Lovelace UI

Hey there,
I just made an icon for some blinds, but they dont scale with the page properly. Is there any setting enable it? I didnt see any with the other svg icons
HAOS Icon Scaling

1 Like

COOOOL

SO if I understand correctly, I can nest card_mod cards inside a state-switch card and use the

        states:
          '(min-width: 1100px)':

To define the max or min width where the entire state switch would be displayed?

I did manage to fix this. For the people with the same problem: The problem was this part of the svg, illustrator generated

<svg id="ecd9de83-d9dc-4bcf-ae4e-56c92cf68072" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" width="150" height="90" viewBox="0 0 206.43 87.53">

It just needs to be like this (with different values)

<svg viewBox="0 0 206.43 87.53">

well, you dont need card-mod to use min-width etc in the state switch card. That is a feature of the card itself.

if you dont would like to use the state-state swtich card i think you can do about the same thing with card mod using the css and min-width/max-width. But i have not tried that myself but i should be possible, look in matthias theme file for some inspiration, he does exactly that.

If you use the custom:button-card you can do it like this:

type: custom:button-card
extra_styles: |
  @media screen and (max-width: 1200px) {
    #card {
      display: none; } 
  }

this card is only shown if the screen is at minimum 1200px in width.

1 Like

If it’s just on/off light you could use the base template instead of light

Hi, friend. Making the changes you put for this month I find this error that I can’t recognize.
Secret apexcharts_tibber not defined
Search all files and can’t find apexcharts_tibber
What to refer to?

Thanks

Forgiveness. I looked elsewhere and couldn’t find it. Thank you very much for continuing to share your changes.

Hello. The card is personalized and therefore the appearance is different. The image in my case was inside the card with a margin and the blur appears above. For that I touch some attributes but I can’t make the blur have rounded edges at the bottom. @Mattias_Persson , can you think of something I can play?
Thank you very much

Sin título

    custom_fields:
      blur:
        - z-index: 1
        - left: -3px
        - top: 15px
        - width: 100%
        - position: absolute
        - border-radius: 25px
        - background-color: rgba(0, 0, 0, 0.2)
        - backdrop-filter: blur(0.4em)
        - -webkit-backdrop-filter: blur(0.4em)
      overlayx:
        - left: 0%
        - width: 100%
        - position: absolute
        - background-color: rgba(255, 255, 255, 0.8)
      media_image:
        - top: -1%
        - left: -1%
        - width: 103%
        - height: 101%
        - position: absolute
        - border-radius: calc(var(--custom-button-card-border-radius) / 2)
        - background-size: cover
        - background-image: >
            [[[
              return entity && variables.entity_picture
                ? `url(${entity.attributes.entity_picture})`
                : 'none';
            ]]]

thanks @Mattias_Persson, no wonder i couldnt find where they got added.
love the work you have done so far keep it up.

1 Like

@Mattias_Persson, can I ask for help on this question of mine?

I would like to have this sensor changing the icon color according to its percentage…
0% remains green and 5% to 100% red.

I already had it working, but it was dependent on a sensor in its “on” state. But I didn’t want to be dependent on that sensor because I don’t have it anymore.

                  - type: custom:button-card
                    entity: sensor.gas_sensor_tuyasns_gas
                    name: '% Gás'
                    tap_action:
                      !include lovelace_ui/another_ui_tablet/popup/segurança_gas_smoke.yaml
                    template:
                      - base
                      - icon_gas_1
                      - loader
  icon_gas_1:
    styles:
      custom_fields:
        icon:
          - width: 92%
          - margin-left: -14%
          - margin-top: -1%
    custom_fields:
      icon: >
        [[[
          const style = `
            <style>
              .on {
                animation: on 1s;
                transform-origin: -100% 46%;
                animation-fill-mode: forwards;
              }
              .off {
                animation: off 1s;
                transform-origin: -100% 46%;
                animation-fill-mode: forwards;
              }
            </style>
          `;       
          const path = `
            <path fill="#2fae81" d="M1.57142849 6.14285713h10.85714302v1.14285716H1.57142849z"/>
            <path fill="#67c7a5" d="M9.00000003 11.28571435H4.99999997c-1.25714288 0-2.28571432-1.02857144-2.28571432-2.28571432V5.28571426C2.71428565 2.91428566 4.62857139.99999991 7 .99999991c2.3714286 0 4.28571435 1.91428574 4.28571435 4.28571435v3.71428577c0 1.25714288-1.02857144 2.28571432-2.28571432 2.28571432z"/>
            <path fill="#a1ecd1" d="m 9.0444711,5.4206731 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.2343749,-0.5290179 1.2343749,-1.234375 0,-0.7053571 -0.5290177,-1.234375 -1.2343749,-1.234375 z"/>"
            <path fill="#a1ecd1" d="m 4.9471153,5.4459135 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.234375,-0.5290179 1.234375,-1.234375 0,-0.7053571 -0.5290178,-1.234375 -1.234375,-1.234375 z" />
            <path fill="#607d8b" d="M7 9.00000003c-1.14285716 0-2.00000003.85714287-2.00000003 2.00000003 0 1.14285716.85714287 2.00000003 2.00000003 2.00000003 1.14285716 0 2.00000003-.85714287 2.00000003-2.00000003 0-1.14285716-.85714287-2.00000003-2.00000003-2.00000003z"/>
            <path fill="#263238" d="M7 9.57142861c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 9.57142861 7 9.57142861zm0 2.28571432c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 11.85714293 7 11.85714293zm-1.22857145-1.5714286c-.08571428.14285715-.02857143.31428572.11428572.40000001.14285714.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857143-.31428571-.11428571-.4-.17142857-.05714286-.31428572-.02857143-.4.11428571zm1.9714286 1.14285717c-.08571428.14285714-.02857142.31428571.11428572.4.14285715.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857144-.31428571-.11428571-.4-.14285714-.05714286-.31428572-.02857143-.4.11428571zm-1.9714286.28571428c.08571429.14285715.25714286.17142858.4.11428572.14285715-.08571429.17142858-.25714286.11428572-.4-.05714285-.14285715-.25714286-.17142858-.4-.11428572-.17142858.08571429-.2.25714286-.11428572.4zm1.9714286-1.14285716c.0857143.14285715.25714287.17142858.40000001.11428572.14285714-.08571429.17142857-.25714286.11428572-.4-.11428572-.14285715-.25714286-.17142858-.40000001-.11428572-.14285714.08571429-.2.25714286-.11428572.4z"/>
          `;
          if (variables.state === 'on' && variables.timeout < 2000) {
            return `
              <svg viewBox="0 0 14 14"> ${style}
                <path fill="#ea3836" d="M1.57142849 6.14285713h10.85714302v1.14285716H1.57142849z"/>
                <path fill="#fa584e" d="M9.00000003 11.28571435H4.99999997c-1.25714288 0-2.28571432-1.02857144-2.28571432-2.28571432V5.28571426C2.71428565 2.91428566 4.62857139.99999991 7 .99999991c2.3714286 0 4.28571435 1.91428574 4.28571435 4.28571435v3.71428577c0 1.25714288-1.02857144 2.28571432-2.28571432 2.28571432z"/>
                <path fill="#ea3836" d="m 9.0444711,5.4206731 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.2343749,-0.5290179 1.2343749,-1.234375 0,-0.7053571 -0.5290177,-1.234375 -1.2343749,-1.234375 z"/>"
                <path fill="#ea3836" d="m 4.9471153,5.4459135 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.234375,-0.5290179 1.234375,-1.234375 0,-0.7053571 -0.5290178,-1.234375 -1.234375,-1.234375 z" />
                <path fill="#607d8b" d="M7 9.00000003c-1.14285716 0-2.00000003.85714287-2.00000003 2.00000003 0 1.14285716.85714287 2.00000003 2.00000003 2.00000003 1.14285716 0 2.00000003-.85714287 2.00000003-2.00000003 0-1.14285716-.85714287-2.00000003-2.00000003-2.00000003z"/>
                <path fill="#ea3836" d="M7 9.57142861c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 9.57142861 7 9.57142861zm0 2.28571432c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 11.85714293 7 11.85714293zm-1.22857145-1.5714286c-.08571428.14285715-.02857143.31428572.11428572.40000001.14285714.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857143-.31428571-.11428571-.4-.17142857-.05714286-.31428572-.02857143-.4.11428571zm1.9714286 1.14285717c-.08571428.14285714-.02857142.31428571.11428572.4.14285715.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857144-.31428571-.11428571-.4-.14285714-.05714286-.31428572-.02857143-.4.11428571zm-1.9714286.28571428c.08571429.14285715.25714286.17142858.4.11428572.14285715-.08571429.17142858-.25714286.11428572-.4-.05714285-.14285715-.25714286-.17142858-.4-.11428572-.17142858.08571429-.2.25714286-.11428572.4zm1.9714286-1.14285716c.0857143.14285715.25714287.17142858.40000001.11428572.14285714-.08571429.17142857-.25714286.11428572-.4-.11428572-.14285715-.25714286-.17142858-.40000001-.11428572-.14285714.08571429-.2.25714286-.11428572.4z"/>
              </svg>
            `;
          }
          if (variables.state === 'on' && variables.timeout > 2000) {
            return `
              <svg viewBox="0 0 14 14"> ${style}
                <path fill="#ea3836" d="M1.57142849 6.14285713h10.85714302v1.14285716H1.57142849z"/>
                <path fill="#fa584e" d="M9.00000003 11.28571435H4.99999997c-1.25714288 0-2.28571432-1.02857144-2.28571432-2.28571432V5.28571426C2.71428565 2.91428566 4.62857139.99999991 7 .99999991c2.3714286 0 4.28571435 1.91428574 4.28571435 4.28571435v3.71428577c0 1.25714288-1.02857144 2.28571432-2.28571432 2.28571432z"/>
                <path fill="#ea3836" d="m 9.0444711,5.4206731 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.2343749,-0.5290179 1.2343749,-1.234375 0,-0.7053571 -0.5290177,-1.234375 -1.2343749,-1.234375 z"/>"
                <path fill="#ea3836" d="m 4.9471153,5.4459135 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.234375,-0.5290179 1.234375,-1.234375 0,-0.7053571 -0.5290178,-1.234375 -1.234375,-1.234375 z" />
                <path fill="#607d8b" d="M7 9.00000003c-1.14285716 0-2.00000003.85714287-2.00000003 2.00000003 0 1.14285716.85714287 2.00000003 2.00000003 2.00000003 1.14285716 0 2.00000003-.85714287 2.00000003-2.00000003 0-1.14285716-.85714287-2.00000003-2.00000003-2.00000003z"/>
                <path fill="#ea3836" d="M7 9.57142861c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 9.57142861 7 9.57142861zm0 2.28571432c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 11.85714293 7 11.85714293zm-1.22857145-1.5714286c-.08571428.14285715-.02857143.31428572.11428572.40000001.14285714.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857143-.31428571-.11428571-.4-.17142857-.05714286-.31428572-.02857143-.4.11428571zm1.9714286 1.14285717c-.08571428.14285714-.02857142.31428571.11428572.4.14285715.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857144-.31428571-.11428571-.4-.14285714-.05714286-.31428572-.02857143-.4.11428571zm-1.9714286.28571428c.08571429.14285715.25714286.17142858.4.11428572.14285715-.08571429.17142858-.25714286.11428572-.4-.05714285-.14285715-.25714286-.17142858-.4-.11428572-.17142858.08571429-.2.25714286-.11428572.4zm1.9714286-1.14285716c.0857143.14285715.25714287.17142858.40000001.11428572.14285714-.08571429.17142857-.25714286.11428572-.4-.11428572-.14285715-.25714286-.17142858-.40000001-.11428572-.14285714.08571429-.2.25714286-.11428572.4z"/>
              </svg>
            `;
          }
          if (variables.state === 'off' && variables.timeout < 2000) {
            return `
              <svg viewBox="0 0 14 14"> ${style}
                <path fill="#2fae81" d="M1.57142849 6.14285713h10.85714302v1.14285716H1.57142849z"/>
                <path fill="#67c7a5" d="M9.00000003 11.28571435H4.99999997c-1.25714288 0-2.28571432-1.02857144-2.28571432-2.28571432V5.28571426C2.71428565 2.91428566 4.62857139.99999991 7 .99999991c2.3714286 0 4.28571435 1.91428574 4.28571435 4.28571435v3.71428577c0 1.25714288-1.02857144 2.28571432-2.28571432 2.28571432z"/>
                <path fill="#a1ecd1" d="m 9.0444711,5.4206731 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.2343749,-0.5290179 1.2343749,-1.234375 0,-0.7053571 -0.5290177,-1.234375 -1.2343749,-1.234375 z"/>"
                <path fill="#a1ecd1" d="m 4.9471153,5.4459135 c -0.7053572,0 -1.234375,0.5290179 -1.234375,1.234375 0,0.7053571 0.5290178,1.234375 1.234375,1.234375 0.7053572,0 1.234375,-0.5290179 1.234375,-1.234375 0,-0.7053571 -0.5290178,-1.234375 -1.234375,-1.234375 z" />
                <path fill="#607d8b" d="M7 9.00000003c-1.14285716 0-2.00000003.85714287-2.00000003 2.00000003 0 1.14285716.85714287 2.00000003 2.00000003 2.00000003 1.14285716 0 2.00000003-.85714287 2.00000003-2.00000003 0-1.14285716-.85714287-2.00000003-2.00000003-2.00000003z"/>
                <path fill="#263238" d="M7 9.57142861c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 9.57142861 7 9.57142861zm0 2.28571432c-.17142857 0-.28571429.11428572-.28571429.28571429s.11428572.28571429.28571429.28571429.28571429-.11428572.28571429-.28571429S7.17142857 11.85714293 7 11.85714293zm-1.22857145-1.5714286c-.08571428.14285715-.02857143.31428572.11428572.40000001.14285714.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857143-.31428571-.11428571-.4-.17142857-.05714286-.31428572-.02857143-.4.11428571zm1.9714286 1.14285717c-.08571428.14285714-.02857142.31428571.11428572.4.14285715.08571429.31428572.02857143.4-.11428572.0857143-.14285714.02857144-.31428571-.11428571-.4-.14285714-.05714286-.31428572-.02857143-.4.11428571zm-1.9714286.28571428c.08571429.14285715.25714286.17142858.4.11428572.14285715-.08571429.17142858-.25714286.11428572-.4-.05714285-.14285715-.25714286-.17142858-.4-.11428572-.17142858.08571429-.2.25714286-.11428572.4zm1.9714286-1.14285716c.0857143.14285715.25714287.17142858.40000001.11428572.14285714-.08571429.17142857-.25714286.11428572-.4-.11428572-.14285715-.25714286-.17142858-.40000001-.11428572-.14285714.08571429-.2.25714286-.11428572.4z"/>
              </svg>
            `;
          } else {
            return `
              <svg viewBox="0 0 14 14"> ${style} 
                ${path}
              </svg>
            `;
          }
        ]]]

image

Thank you

if (parseFloat(entity.state) >= 0 && parseFloat(entity.state) < 5) {
  green svg
} else {
  red svg
}
1 Like

overlayx etc are the old config, you have to add the new changes

1 Like

Replace entire theme. recharge it.
Add extra_styles.
Change base,
base_media, media, and conditional_media. Now I find that which looks like a rectangle. An object that looks like blur and the text that escapes the outline. What could I check?

Sin título

The other thing that gives me an error is entity.attributes.data; For example spotify does not contain data. Where does this data come from? Thanks

conditional_media:
  aspect_ratio: 1000/996
  template:
    - base
    #- media_youtube
    - icon_play_pause
  variables:
    i: >
      [[[
        let data = entity.attributes.data;
        if (entity && data) {
          return Math.floor(Math.random() * (data.length - 1)) + 1;
        }
      ]]]

Any way how to include Time and date to Iphone or any phone ios

  [[[
        if (entity) {
          let attr = [];
          for (let [k, value] of Object.entries(entity.attributes))
            window.navigator.userAgent.match(/iPhone/i)
              ? k !== 'time' && k !== 'date' && value !== false && (attr += `<p>${k === 'greet' ? `<span class="iphone">${value}</span>` : `${value}`}</p>`)
              : value !== false && (attr += `<p>${value}</p>`);
          return attr;
        }
      ]]]

@Mattias_Persson, thank you very much for this beautiful dashboard. Your instructions are clear and I’ve spent the better part of 2 months trying to cobble something together. I went from knowing nothing to knowing just a bit less than nothing! I’ve even made some pretty cool (I think) SVG animated icons!

I am having trouble with a scenario I’d like to implement for our ceiling fans (Lutron Caseta). I piggybacked off your light-popup-card idea and tried to apply it to our fans, effectively providing me the option of choose a fan speed.

I’ve created a new fan template (below) and utilized the browser_mod popup command (tap_action) to display custom button cards (attached image), each card representing a fan setting. What I have been trying to do is change the background colour of the selected fan setting. It does work when I close and reopen the popup, but the popup is not dynamically updating. E.g. click low, the button background colour should update immediately.

When I click on a setting, then close the popup and open it again, the associated button has it’s background colour changed. No other actions will update this background colour except if I was to click the off button. Changing the fan state actually causes updates to the button backgrounds. This leads me to believe that I need to monitor the percentage attribute some how, or have it trigger updates, but I have no idea how to do that!

I don’t expect you to fix this for me, but I am hoping you can point me in the right direction so I can research further. I think the root of my issue is that percentage attribute doesn’t cause event changes and I need it to - but I don’t know how.

I thank you for any guidance you can provide.

image

  fan:
    template:
      - base
      - circle
    variables:
      circle_input: |
        [[[ return entity === undefined || entity.attributes.percentage; ]]] 
    tap_action:
      action: fire-dom-event
      browser_mod:
        command: popup
        title: >
          [[[ return entity === undefined || entity.attributes.friendly_name;
          ]]]
        card:
          type: vertical-stack
          entity_id: |
            [[[ return variables.entity_id; ]]] 
          cards:
            - type: custom:button-card
              entity: |
                [[[ return variables.entity_id; ]]] 
              name: High
              show_label: true
              tap_action:
                action: call-service
                service: fan.set_percentage
                service_data:
                  entity_id: |
                    [[[ return variables.entity_id; ]]]  
                  percentage: 100
              show_icon: false
              show_state: false
              styles:
                card:
                  - border-radius: 8%
                    background-color: |
                      [[[
                        if(variables.circle_input == 100) return 'var(--button-card-light-color)';                        
                      ]]] 
                name:
                  - justify-self: center
#. 
#.
#.....additional fan settings
#.
#.
            - type: custom:button-card
              entity: |
                [[[ return variables.entity_id; ]]] 
              name: 'Off'
              tap_action:
                action: call-service
                service: fan.turn_off
                service_data:
                  entity_id: |
                    [[[ return variables.entity_id; ]]]  
              show_icon: false
              show_state: false
              styles:
                card:
                  - border-radius: 8%
                name:
                  - justify-self: center

Have you tried triggers_update?

@Mattias_Persson; there seems to be a layout-margin added recently. I’m not sure where it comes from. It might be after I updated and got the new UI.

This seems to come from ‘grid-layout’, but I’m not sure:
“#view>hui-view>grid-layout$#root>hui-vertical-stack-card”

This is added:
–layout-margin: 4px 4px 0px 4px;

Creating a border that is barely noticeable, but it’s enough for a scroll bar to appear.
image