找回密码
 立即注册

微信扫码登录

搜索
查看: 402|回复: 19

[UI界面] 自制卡片分享,popup-button-card,一个自带弹窗的按钮卡片

[复制链接]

32

主题

239

回帖

2017

积分

论坛UI达人

积分
2017
金钱
1741
HASS币
50
发表于 前天 12:47 | 显示全部楼层 |阅读模式
少废话,先上图

动画.webp



弹窗方案之前最早用的broswer-mod,这货除了弹窗功能外还附带了很多杂七杂八的东西,而且弹窗比较死板,兼容性也不好,用了不久就放弃了;
后面换为了bubble-card的popup子卡片,效果蛮好,功能丰富,但是弹窗样式修改不友好,动点啥都要去趴css样式,能实现的效果也比较受限;


于是我就琢磨自己搞,新弹窗卡!由于没有编程基础,只能依靠ai代劳,在与gpt大战300回合后,终于是把基础功能搓出来了
我将其命名为popup-button-card,为我的主力卡片button-card特别做了兼容适配,以加入到button-card的嵌套大军中,目标用法是:
{240CD6E8-1349-4BEF-975B-F042285EAB98}.png
不过单独使用也没毛病,这个是设计基础

效果说明:
  • 图标和文本支持模板语法动态设置,支持布局自定,哪个上哪个下哪个左哪个右自己决定
image.png
  • 弹窗展开状态下,按钮可配置凸显效果(图中深蓝底边),凸显的颜色可自定,支持模板语法动态设置
{9F0A98AC-C8C5-40A0-8CB2-D44078285F16}.png
  • 弹窗位置可选上下左右(相对于按钮位置)
image.png
  • 任何弹窗外的交互都会自动收起弹窗(当然再次点击按钮也会),可选配置是否在滑动屏幕时关闭弹窗(适配一些超过屏幕高度的弹窗),如图:
动画2.webp

  • 目前只支持单一弹窗同时存在,弹窗打开状态点击其他弹窗,会自动收起前一弹窗
动画3.webp


  • 弹窗是浮层式的,不展开时不占用卡片位置,不需预留空间,展开时浮与其他元素之上,弹窗大小可自定义,不受父卡片限制
动画4.webp

  • 弹窗内可嵌套任意官方、第三方卡片(理论上)



  • 更多效果可自行体验




安装方法:
1、下载卡片js文件:
游客,如果您要查看本帖隐藏内容请回复

2、将js文件放入ha的config/www目录,比如/config/www/community/popup-button-card/popup_button_card.js(先新建popup-button-card文件夹)
3、进入ha的设置页面->仪表盘->右上角3个点->资源->右下角添加资源
4、如果你放进去的时上面的示例路径,那网址就填/local/community/popup-button-card/popup_button_card.js,其他地方就把/config/www/换为/lcoal/,再接具体路径,资源类型为JavaScript 模块
5、添加之后,清除浏览器缓存,ctrl+f5强制刷新,点击新建卡片,往下滑,如正常安装就会看到这个卡片,如图
image.png
如没有,检查f12控制台->网络,检查是否有加载到popup_button_card.js,如果提示错误,检查js文件的执行权限


示例配置
type: custom:popup-button-card    #固定首行,不可变
unique_id: xxxx11122333     #唯一id,用于弹窗机制,可配置任意字母数字,不重复即可
name: 示例名称
#name: |    #或模板写法,以空调为例
#   [[[
#       var state = states[`climate.entity`].state;
#       if (state === "off"){
#         return "已关机";
#       } else if (state === "cool"){
#         return "制冷模式";
#       } else if (state === "heat"){
#         return "制热模式";
#       } else if (state === "dry"){
#         return "除湿模式";
#       } else if (state === "fan_only"){
#         return "送风模式";
#       } else if (state === "auto"){
#         return "自动模式";
#       } else {
#         return "未 知";
#       }
#   ]]]
button_icon: mdi:xxxxx   #支持内置mdi图标,或图标文件url路径
#button_icon: /local/path_to_your_file    #文件路径写法
#button_icon: |    #模板写法,以开关为例,on/off返回不同图标
#   [[[
#       var state = states[`switch.entity`].state;
#        if (state === "on"){
#          return "/local/switch_on.svg"
#        } else {
#          return "/local/switch_off.svg"
#        }
#   ]]]
expand_side: bottom   #弹窗出现的方向,接受top/bottom/left/right
expand_area_grid: 0px  #弹窗与按钮之间的空隙距离
button_effect: true    #true/false , 是否开启弹窗打开后,按钮的额外视觉效果
button_effect_color: "#D7DFED"  #上一条按钮额外视觉效果的颜色选项,接受html颜色代码或rgb值,html颜色代码记得使用双引号括起来
#button_effect_color: rgb(255,255,255)  #rgb值写法
#button_effect_color: |    #模板写法,以空调为例
#   [[[
#       var state = states[`climate.entity`].state
#       if (state === "off"){
#         return "#D7DFED"
#       } else if (state === "cool"){
#         return "#2483FF"
#       } else if (state === "heat"){
#         return "#FF6B6B"
#       } else if (state === "dry"){
#         return "#54CEAE"
#       } else if (state === "fan_only"){
#         return "#4CCBA9"
#       } else if (state === "auto"){
#         return "#464BD8"
#       } else {
#         return "#D7DFED"
#       }
#   ]]]
updown_slide_to_close_popup: true  #true/false , 页面上下滑动时,是否自动关闭弹窗
styles:    # css styles 属性配置,此部分与button-card雷同,通用css样式基本都可配置
  content:   #content字段,负责配置弹窗容器的样式
    - box-shadow: none  #关闭阴影
    - background: rgba(0,0,0,0) #透明背景
    - margin-top: "-13px"   #弹窗整体上下位移
    - margin-left: "-10px"  #弹窗整体左右位移
  button:   #button字段,负责配置按钮的样式
    - height: 70px  #按钮高度
    - width: 70px   #按钮宽度
    - background: |  #按钮背景色,与上面button_effect_color写法一致
        [[[
            var state = states[`climate.entity`].state
            if (state === "off"){
              return "#D7DFED"
            } else if (state === "cool"){
              return "#C9E9F9"
            } else if (state === "heat"){
              return "#F4CECE"
            } else if (state === "dry"){
              return "#C8F4E8"
            } else if (state === "fan_only"){
              return "#ACF1B0"
            } else if (state === "auto"){
              return "#BABCE8"
            } else {
              return "#D7DFED"
            }
        ]]]
    - border-radius: 20px   #按钮圆角
  name:   #name字段,负责文本内容样式控制
    - font-weight: bold   #文本加粗
    - font-size: 14px   #字体大小
    - color: rgb(85,110,127)  #字体颜色
    - letter-spacing: 1px  #字符间距
    - margin-left: 2px  #整体左右位移
  icon:  #icon字段,负责图标样式控制
    - width: 50px   #图标高度
    - height: 50px  #图标宽度
    - color: white  #图标颜色
  grid:  #grid字段,负责图标与文本的布局形式
    - display: grid
    - grid-template-areas: |  #"i"代表icon,图标,“n”代表name文本,它们上下左右排布会对应到按钮布局上,比如这里icon位于name上方
        "i"
        "n"
    - grid-template-columns: auto  #列宽度
    - grid-template-rows: 45px 25px #行宽度
    - justify-items: center #水平对齐方式,start/center/end
content:  #content弹窗内容
  card:  #可以在此后面衔接任意卡片代码,将会出现在弹窗容器中
    type: custom:button-card

测试反馈:
目前这个卡片我还在试用阶段,铺开使用还需要测试,不过基本功能没有出现什么问题;
已在PC端edge/chrome/firefox测试通过
ios、安卓官方客户端也未见毛病,大家可尝试使用,留言反馈bug,我会继续大战ai 300回合


✅以上~
{B46625F0-E11A-4440-8DEE-E8963C1BFA14}.png

评分

参与人数 3金钱 +30 收起 理由
Tamaki + 5 高手,这是高手!
sorrypqa + 20 大神666!
lc0888 + 5 赠人玫瑰,手留余香!

查看全部评分

回复

使用道具 举报

64

主题

1629

回帖

1万

积分

元老级技术达人

积分
13276
金钱
11573
HASS币
80
发表于 前天 14:19 | 显示全部楼层
broswer-mod这玩意的确不好用,各种疑难杂症
回复

使用道具 举报

1

主题

45

回帖

352

积分

中级会员

积分
352
金钱
306
HASS币
0
发表于 前天 15:13 | 显示全部楼层
学习学习
回复

使用道具 举报

7

主题

83

回帖

1761

积分

金牌会员

积分
1761
金钱
1671
HASS币
0
发表于 前天 15:22 | 显示全部楼层
学习学习学习学习
回复

使用道具 举报

1

主题

45

回帖

352

积分

中级会员

积分
352
金钱
306
HASS币
0
发表于 前天 16:03 | 显示全部楼层
  expand_side: left   #弹窗出现的方向,接受top/bottom/left/right,
            content:  #content弹窗内容
              card:  #可以在此后面衔接任意卡片代码,将会出现在弹窗容器中
                # type: custom:button-card

                # type: vertical-stack
                type: vertical-stack
                # card_mod:
                #   style: |
                #     ha-card {
                #       background: white;
                #       border-radius: 12px;
                #       padding: 16px;
                #       box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                #     }
                cards:
                  - type: horizontal-stack



                    # title: 用电状态
                    cards:
                      - type: sensor
                        entity: sensor.watermetertest_yongliang
                        name: 水表量
                        icon: mdi:home-lightning-bolt-outline
                      - type: sensor
                        entity: sensor.jin_ri_yong_shui_liang
                        name: 今日用水量
                        icon: mdi:home-lightning-bolt-outline
                        detail: 1
                      - type: sensor
                        entity: sensor.zuo_ri_yong_shui_liang
                        name: 昨日用水量
                        icon: mdi:home-lightning-bolt-outline
                        # unit: 元
                        detail: 1

怎么设置都在右下角,然后总是有一段距离是怎么回事
QQ_1758960156569.png
回复

使用道具 举报

32

主题

239

回帖

2017

积分

论坛UI达人

积分
2017
金钱
1741
HASS币
50
 楼主| 发表于 前天 17:32 | 显示全部楼层
Zuray 发表于 2025-9-27 16:03
expand_side: left   #弹窗出现的方向,接受top/bottom/left/right,
            content:  #content弹 ...

代码和截图贴全一些,现在看不出问题
回复

使用道具 举报

0

主题

36

回帖

839

积分

高级会员

积分
839
金钱
803
HASS币
0
发表于 前天 18:28 | 显示全部楼层
学习学习
回复

使用道具 举报

1

主题

45

回帖

352

积分

中级会员

积分
352
金钱
306
HASS币
0
发表于 前天 19:19 | 显示全部楼层
          - type: custom:popup-button-card    #固定首行,不可变
            unique_id: xxxx11122333     #唯一id,用于弹窗机制,可配置任意字母数字,不重复即可
            name: 示例名称

            style:
              left: 380px
              top: 180px
              width: 30px
              height: 56px
            #name: |    #或模板写法,以空调为例
            #   [[[
            #       var state = states[`climate.entity`].state;
            #       if (state === "off"){
            #         return "已关机";
            #       } else if (state === "cool"){
            #         return "制冷模式";
            #       } else if (state === "heat"){
            #         return "制热模式";
            #       } else if (state === "dry"){
            #         return "除湿模式";
            #       } else if (state === "fan_only"){
            #         return "送风模式";
            #       } else if (state === "auto"){
            #         return "自动模式";
            #       } else {
            #         return "未 知";
            #       }
            #   ]]]
            button_icon: mdi:xxxxx   #支持内置mdi图标,或图标文件url路径
            #button_icon: /local/path_to_your_file    #文件路径写法
            #button_icon: |    #模板写法,以开关为例,on/off返回不同图标
            #   [[[
            #       var state = states[`switch.entity`].state;
            #        if (state === "on"){
            #          return "/local/switch_on.svg"
            #        } else {
            #          return "/local/switch_off.svg"
            #        }
            #   ]]]
            expand_side: left   #弹窗出现的方向,接受top/bottom/left/right
            expand_area_grid: 0px  #弹窗与按钮之间的空隙距离
            button_effect: true    #true/false , 是否开启弹窗打开后,按钮的额外视觉效果
            button_effect_color: "#D7DFED"  #上一条按钮额外视觉效果的颜色选项,接受html颜色代码或rgb值,html颜色代码记得使用双引号括起来
            #button_effect_color: rgb(255,255,255)  #rgb值写法
            #button_effect_color: |    #模板写法,以空调为例
            #   [[[
            #       var state = states[`climate.entity`].state
            #       if (state === "off"){
            #         return "#D7DFED"
            #       } else if (state === "cool"){
            #         return "#2483FF"
            #       } else if (state === "heat"){
            #         return "#FF6B6B"
            #       } else if (state === "dry"){
            #         return "#54CEAE"
            #       } else if (state === "fan_only"){
            #         return "#4CCBA9"
            #       } else if (state === "auto"){
            #         return "#464BD8"
            #       } else {
            #         return "#D7DFED"
            #       }
            #   ]]]
            updown_slide_to_close_popup: true  #true/false , 页面上下滑动时,是否自动关闭弹窗
            styles:    # css styles 属性配置,此部分与button-card雷同,通用css样式基本都可配置
              content:   #content字段,负责配置弹窗容器的样式
                - box-shadow: none  #关闭阴影
                - background: rgba(0,0,0,0) #透明背景
                - margin-top: "13px"   #弹窗整体上下位移
                - margin-left: "10px"  #弹窗整体左右位移
              button:   #button字段,负责配置按钮的样式
                - height: 70px  #按钮高度
                - width: 70px   #按钮宽度
                - background: |  #按钮背景色,与上面button_effect_color写法一致
                    [[[
                        var state = states[`climate.entity`].state
                        if (state === "off"){
                          return "#D7DFED"
                        } else if (state === "cool"){
                          return "#C9E9F9"
                        } else if (state === "heat"){
                          return "#F4CECE"
                        } else if (state === "dry"){
                          return "#C8F4E8"
                        } else if (state === "fan_only"){
                          return "#ACF1B0"
                        } else if (state === "auto"){
                          return "#BABCE8"
                        } else {
                          return "#D7DFED"
                        }
                    ]]]
                - border-radius: 20px   #按钮圆角
              name:   #name字段,负责文本内容样式控制
                - font-weight: bold   #文本加粗
                - font-size: 14px   #字体大小
                - color: rgb(85,110,127)  #字体颜色
                - letter-spacing: 1px  #字符间距
                - margin-left: 2px  #整体左右位移
              icon:  #icon字段,负责图标样式控制
                - width: 50px   #图标高度
                - height: 50px  #图标宽度
                - color: white  #图标颜色
              grid:  #grid字段,负责图标与文本的布局形式
                - display: grid
                - grid-template-areas: |  #"i"代表icon,图标,“n”代表name文本,它们上下左右排布会对应到按钮布局上,比如这里icon位于name上方
                    "i"
                    "n"
                - grid-template-columns: auto  #列宽度
                - grid-template-rows: 45px 25px #行宽度
                - justify-items: start #水平对齐方式,start/center/end
            content:  #content弹窗内容
              card:  #可以在此后面衔接任意卡片代码,将会出现在弹窗容器中
                # type: custom:button-card

                # type: vertical-stack
                type: vertical-stack
                # card_mod:
                #   style: |
                #     ha-card {
                #       background: white;
                #       border-radius: 12px;
                #       padding: 16px;
                #       box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                #     }
                cards:
                  - type: horizontal-stack



                    # title: 用电状态
                    cards:
                      - type: sensor
                        entity: sensor.watermetertest_yongliang
                        name: 水表量
                        icon: mdi:home-lightning-bolt-outline
                      - type: sensor
                        entity: sensor.jin_ri_yong_shui_liang
                        name: 今日用水量
                        icon: mdi:home-lightning-bolt-outline
                        detail: 1
                      - type: sensor
                        entity: sensor.zuo_ri_yong_shui_liang
                        name: 昨日用水量
                        icon: mdi:home-lightning-bolt-outline
                        # unit: 元
                        detail: 1

                  



QQ_1758971934217.png
回复

使用道具 举报

32

主题

239

回帖

2017

积分

论坛UI达人

积分
2017
金钱
1741
HASS币
50
 楼主| 发表于 前天 20:44 | 显示全部楼层
Zuray 发表于 2025-9-27 19:19
- type: custom:popup-button-card    #固定首行,不可变
            unique_id: xxxx11122333  ...

不要乱加style字段,自带的styles已经支持通用css样式修改

你想改弹窗大小,直接在styles.content内改就行了
type: custom:popup-button-card    #固定首行,不可变
unique_id: xxxx11122333
name: 示例名称
button_icon: mdi:xxxxx   #支持内置mdi图标,或图标文件url路径
expand_side: left   #弹窗出现的方向,接受top/bottom/left/right
expand_area_grid: 0px  #弹窗与按钮之间的空隙距离
button_effect: true    #true/false , 是否开启弹窗打开后,按钮的额外视觉效果
button_effect_color: "#D7DFED"  #上一条按钮额外视觉效果的颜色选项,接受html颜色代码或rgb值,html颜色代码记得使用双引号括起来
updown_slide_to_close_popup: true  #true/false , 页面上下滑动时,是否自动关闭弹窗
styles:    # css styles 属性配置,此部分与button-card雷同,通用css样式基本都可配置
  content:   #content字段,负责配置弹窗容器的样式
    - box-shadow: none  #关闭阴影
    - background: rgba(0,0,0,0) #透明背景
    - margin-top: "13px"   #弹窗整体上下位移
    - margin-left: "10px"  #弹窗整体左右位移
    - width: 30px
    - height: 56px
  button:   #button字段,负责配置按钮的样式
    - height: 70px  #按钮高度
    - width: 70px   #按钮宽度
    - background: blue
    - border-radius: 20px   #按钮圆角
  name:   #name字段,负责文本内容样式控制
    - font-weight: bold   #文本加粗
    - font-size: 14px   #字体大小
    - color: rgb(85,110,127)  #字体颜色
    - letter-spacing: 1px  #字符间距
    - margin-left: 2px  #整体左右位移
  icon:  #icon字段,负责图标样式控制
    - width: 50px   #图标高度
    - height: 50px  #图标宽度
    - color: white  #图标颜色
  grid:  #grid字段,负责图标与文本的布局形式
    - display: grid
    - grid-template-areas: |  #"i"代表icon,图标,“n”代表name文本,它们上下左右排布会对应到按钮布局上,比如这里icon位于name上方
        "i"
        "n"
    - grid-template-columns: auto  #列宽度
    - grid-template-rows: 45px 25px #行宽度
    - justify-items: start #水平对齐方式,start/center/end
  content:  #content弹窗内容
    card:  #可以在此后面衔接任意卡片代码,将会出现在弹窗容器中
      type: vertical-stack
      cards:
        - type: horizontal-stack
          cards:
            - type: sensor
              entity: sensor.watermetertest_yongliang
              name: 水表量
              icon: mdi:home-lightning-bolt-outline
            - type: sensor
              entity: sensor.jin_ri_yong_shui_liang
              name: 今日用水量
              icon: mdi:home-lightning-bolt-outline
              detail: 1
            - type: sensor
              entity: sensor.zuo_ri_yong_shui_liang
              name: 昨日用水量
              icon: mdi:home-lightning-bolt-outline
              # unit: 元
              detail: 1


回复

使用道具 举报

mhbj 手机认证

5

主题

42

回帖

267

积分

中级会员

积分
267
金钱
220
HASS币
0
发表于 前天 20:53 | 显示全部楼层
学习以下,这个不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )

GMT+8, 2025-9-29 04:35 , Processed in 0.714003 second(s), 13 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表