Dashboard 2.0 icons in html-template-node

I am trying to create my own button-toggle component with an html-template-node.The logic works so far. However, I can't get it to work with icons. They are not rendered for me.The icons work fine in a standard Dashboard 2.0 button-group-node.How do I integrate them correctly into the html-template-node?

Example

[
    {
        "id": "155d7a767c816aa9",
        "type": "inject",
        "z": "23f984cab29f3522",
        "name": "Set Initial States",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"power\":true,\"light\":false,\"fan\":false,\"settings\":true}",
        "payloadType": "json",
        "x": 90,
        "y": 140,
        "wires": [
            [
                "d8f5ad2451889c9a"
            ]
        ]
    },
    {
        "id": "d8f5ad2451889c9a",
        "type": "ui-template",
        "z": "23f984cab29f3522",
        "group": "ui-group-1",
        "page": "",
        "ui": "",
        "name": "Toggle Button Group",
        "order": 1,
        "width": "6",
        "height": "3",
        "head": "<link href=\"https://fonts.googleapis.com/icon?family=Material+Icons\" rel=\"stylesheet\">",
        "format": "<template>\n    <div class=\"toggle-widget-container\">\n        <div :style=\"containerStyles\" class=\"toggle-button-group\">\n            <div \n                v-for=\"(button, index) in buttons\" \n                :key=\"button.name\"\n                :class=\"['toggle-btn', { \n                    'active': toggleStates[button.name], \n                    'first': index === 0, \n                    'last': index === buttons.length - 1 \n                }]\"\n                :style=\"getButtonStyle(button.name, index)\"\n                @click=\"toggleButton(button.name)\"\n                @mouseenter=\"showTooltip(button.name, $event)\"\n                @mouseleave=\"hideTooltip\"\n                :title=\"button.tooltip\"\n            >\n                <i :class=\"getIconClass(button.icon)\" class=\"material-icons\">{{ getIconName(button.icon) }}</i>\n            </div>\n        </div>\n        \n        <div v-if=\"tooltipVisible\" class=\"tooltip\" :style=\"tooltipStyle\">\n            {{ getTooltipText(tooltipVisible) }}\n        </div>\n    </div>\n</template>\n\n\n<script>\nexport default {\n    data() {\n        return {\n            toggleStates: {\n                'power': false,\n                'light': false,\n                'fan': false,\n                'settings': false\n            },\n            config: {\n                border: 1,\n                size: '35px',\n                position: 'bottom-right',\n                distance: 5,\n                color: {\n                    active: '#2196F3',\n                    inactive: '#FFFFFF',\n                    hover: '#BBDEFB',\n                    border: '#E0E0E0'\n                }\n            },\n            buttons: [\n                { name: 'config', icon: 'hammer-screwdriver', tooltip: 'cinfig' },\n                { name: 'charts', icon: 'chart-line', tooltip: 'charts' },\n                { name: 'temperature', icon: 'temperature-celsius', tooltip: 'Temperature Control' },\n                { name: 'humidifier', icon: 'air-humidifier', tooltip: 'humidifier Control' }\n            ],\n            tooltipVisible: null,\n            tooltipStyle: {}\n        };\n    },\n    computed: {\n        containerStyles() {\n            const pos = this.config.position || 'bottom-right';\n            const distance = `${this.config.distance || 5}px`;\n            \n            let positioning = {};\n            \n            if (pos.includes('bottom')) {\n                positioning.bottom = distance;\n            } else if (pos.includes('top')) {\n                positioning.top = distance;\n            }\n            \n            if (pos.includes('right')) {\n                positioning.right = distance;\n            } else if (pos.includes('left')) {\n                positioning.left = distance;\n            }\n            \n            return {\n                position: 'absolute',\n                display: 'flex',\n                zIndex: 1000,\n                ...positioning\n            };\n        }\n    },\n    methods: {\n        toggleButton(buttonName) {\n            const newState = !this.toggleStates[buttonName];\n            this.toggleStates[buttonName] = newState;\n            \n            // Send message to Node-RED\n            this.send({\n                payload: {\n                    [buttonName]: newState\n                },\n                timestamp: Date.now()\n            });\n        },\n        \n        getButtonStyle(buttonName, index) {\n            const size = this.config.size || '35px';\n            const border = this.config.border || 1;\n            const colors = this.config.color || {\n                active: '#2196F3',\n                inactive: '#FFFFFF',\n                hover: '#BBDEFB',\n                border: '#E0E0E0'\n            };\n            \n            const isActive = this.toggleStates[buttonName];\n            const isFirst = index === 0;\n            const isLast = index === this.buttons.length - 1;\n            \n            let backgroundColor = colors.inactive;\n            let textColor = '#666';\n            \n            if (isActive) {\n                backgroundColor = colors.active;\n                textColor = 'white';\n            }\n            \n            return {\n                width: size,\n                height: size,\n                backgroundColor: backgroundColor,\n                color: textColor,\n                border: `${border}px solid ${colors.border}`,\n                borderRight: isLast ? `${border}px solid ${colors.border}` : 'none',\n                borderRadius: '0',\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'center',\n                cursor: 'pointer',\n                transition: 'all 0.2s ease',\n                userSelect: 'none',\n                boxSizing: 'border-box'\n            };\n        },\n        \n        getIconClass(icon) {\n            return 'material-icons';\n        },\n        \n        getIconName(icon) {\n            return icon;\n        },\n        \n        getTooltipText(buttonName) {\n            const button = this.buttons.find(b => b.name === buttonName);\n            return button ? button.tooltip : '';\n        },\n        \n        showTooltip(buttonName, event) {\n            this.tooltipVisible = buttonName;\n            \n            const rect = event.target.getBoundingClientRect();\n            this.tooltipStyle = {\n                position: 'fixed',\n                top: (rect.top - 35) + 'px',\n                left: (rect.left + rect.width / 2) + 'px',\n                transform: 'translateX(-50%)',\n                backgroundColor: 'rgba(0, 0, 0, 0.8)',\n                color: 'white',\n                padding: '6px 10px',\n                borderRadius: '4px',\n                fontSize: '12px',\n                whiteSpace: 'nowrap',\n                zIndex: 10001,\n                pointerEvents: 'none'\n            };\n        },\n        \n        hideTooltip() {\n            this.tooltipVisible = null;\n        }\n    },\n    \n    watch: {\n        msg: {\n            handler(newMsg) {\n                if (newMsg && newMsg.payload) {\n                    // Update states from incoming message\n                    Object.assign(this.toggleStates, newMsg.payload);\n                }\n                \n                if (newMsg && newMsg.config) {\n                    // Update configuration from incoming message\n                    Object.assign(this.config, newMsg.config);\n                }\n                \n                if (newMsg && newMsg.buttons) {\n                    // Update button definitions from incoming message\n                    this.buttons = newMsg.buttons;\n                    \n                    // Initialize states for new buttons\n                    newMsg.buttons.forEach(button => {\n                        if (!(button.name in this.toggleStates)) {\n                            this.$set(this.toggleStates, button.name, false);\n                        }\n                    });\n                }\n            },\n            deep: true\n        }\n    }\n}\n</script>\n\n<style scoped>\n.toggle-widget-container {\n    position: relative;\n    height: 100%;\n    width: 100%;\n}\n\n.toggle-button-group {\n    display: flex;\n    box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n}\n\n.toggle-btn {\n    transition: all 0.2s ease;\n}\n\n.toggle-btn:hover {\n    background-color: #BBDEFB !important;\n    z-index: 1;\n}\n\n.toggle-btn.active:hover {\n    background-color: #1976D2 !important;\n}\n\n.tooltip {\n    position: fixed;\n    background-color: rgba(0, 0, 0, 0.8);\n    color: white;\n    padding: 6px 10px;\n    border-radius: 4px;\n    font-size: 12px;\n    white-space: nowrap;\n    z-index: 10001;\n    pointer-events: none;\n}\n\n.material-icons {\n    font-size: 18px;\n    line-height: 1;\n}\n</style>",
        "storeOutMessages": true,
        "passthru": false,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 300,
        "y": 200,
        "wires": [
            [
                "422345191feb1813"
            ]
        ]
    },
    {
        "id": "422345191feb1813",
        "type": "debug",
        "z": "23f984cab29f3522",
        "name": "Toggle Output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 200,
        "wires": []
    },
    {
        "id": "ui-group-1",
        "type": "ui-group",
        "name": "Toggle Button Group",
        "page": "ui-page-1",
        "width": "6",
        "height": "1",
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": true,
        "disabled": false
    },
    {
        "id": "ui-page-1",
        "type": "ui-page",
        "name": "Test Page",
        "ui": "1f09dc2ae6515591",
        "path": "/toggle-test",
        "icon": "home",
        "layout": "grid",
        "theme": "ui-theme-1",
        "order": 2,
        "className": "",
        "visible": true,
        "disabled": false
    },
    {
        "id": "1f09dc2ae6515591",
        "type": "ui-base",
        "name": "My Dashboard 2.0",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "temporary",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "ui-theme-1",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094ce",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "75ec18fe22e66bed",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.26.0"
        }
    }
]

I imported your flow but all I got displayed was a blur of overwritten text.

This is a basic template button with icon. btnBasic & iconBasic classes just define the sizes, the two :class definitions just determine the colour. In this particular button the button text is above the icon, but I think for your purposes you are only interested in the <v-icon></v-icon> line

I vary the icon dependant on switch toggle by using {{iconImage}}, instead of a fixed image, and then computing the image required (for example ['mdi-light-switch-off', 'mdi-light-switch'])

        <v-btn class = "btnBasic" :class = "btnClass" stacked @click="changeState()">
            {{btnText}}
            <v-icon class = "iconBasic" :class = "iconClass" >mdi-lightbulb-variant-outline</v-icon

        </v-btn>

Apologies, I realised what your problem was, Please find attached edited copy of your ui-template node. Changes are shown as v1.1

[{"id":"155d7a767c816aa9","type":"inject","z":"506727cd93754bdb","name":"Set Initial States","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"{\"power\":true,\"light\":false,\"fan\":false,\"settings\":true}","payloadType":"json","x":900,"y":1740,"wires":[["d8f5ad2451889c9a"]]},{"id":"d8f5ad2451889c9a","type":"ui-template","z":"506727cd93754bdb","group":"b93577c7977b9d29","page":"","ui":"","name":"Toggle Button Group","order":1,"width":"6","height":"3","head":"<link href=\"https://fonts.googleapis.com/icon?family=Material+Icons\" rel=\"stylesheet\">","format":"<template>\n    <div class=\"toggle-widget-container\">\n        <div :style=\"containerStyles\" class=\"toggle-button-group\">\n            <div \n                v-for=\"(button, index) in buttons\" \n                :key=\"button.name\"\n                :class=\"['toggle-btn', { \n                    'active': toggleStates[button.name], \n                    'first': index === 0, \n                    'last': index === buttons.length - 1 \n                }]\"\n                :style=\"getButtonStyle(button.name, index)\"\n                @click=\"toggleButton(button.name)\"\n                @mouseenter=\"showTooltip(button.name, $event)\"\n                @mouseleave=\"hideTooltip\"\n                :title=\"button.tooltip\"\n            >\n                <v-icon :class=\"getIconClass()\">{{getIconName(index)}}</v-icon>                                  <!-- v1.1 -->\n            </div>\n        </div>\n        \n        <div v-if=\"tooltipVisible\" class=\"tooltip\" :style=\"tooltipStyle\">\n            {{ getTooltipText(tooltipVisible) }}\n        </div>\n    </div>\n</template>\n\n\n<script>\nexport default {\n    data() {\n        return {\n            toggleStates: {\n                'power': false,\n                'light': false,\n                'fan': false,\n                'settings': false\n            },\n            config: {\n                border: 1,\n                size: '35px',\n                position: 'bottom-right',\n                distance: 5,\n                color: {\n                    active: '#2196F3',\n                    inactive: '#FFFFFF',\n                    hover: '#BBDEFB',\n                    border: '#E0E0E0'\n                }\n            },\n            buttons: [\n                { name: 'config', icon: 'mdi-hammer-screwdriver', tooltip: 'Config' },                          // v1.1                \n                { name: 'charts', icon: 'mdi-chart-line', tooltip: 'charts' },                                  // v1.1\n                { name: 'temperature', icon: 'mdi-temperature-celsius', tooltip: 'Temperature Control' },       // v1.1\n                { name: 'humidifier', icon: 'mdi-air-humidifier', tooltip: 'Humidifier Control' }               // v1.1\n            ],\n            tooltipVisible: null,\n            tooltipStyle: {}\n        };\n    },\n    computed: {\n        containerStyles() {\n            const pos = this.config.position || 'bottom-right';\n            const distance = `${this.config.distance || 5}px`;\n            \n            let positioning = {};\n            \n            if (pos.includes('bottom')) {\n                positioning.bottom = distance;\n            } else if (pos.includes('top')) {\n                positioning.top = distance;\n            }\n            \n            if (pos.includes('right')) {\n                positioning.right = distance;\n            } else if (pos.includes('left')) {\n                positioning.left = distance;\n            }\n            \n            return {\n                position: 'absolute',\n                display: 'flex',\n                zIndex: 1000,\n                ...positioning\n            };\n        }\n    },\n    methods: {\n        toggleButton(buttonName) {\n            const newState = !this.toggleStates[buttonName];\n            this.toggleStates[buttonName] = newState;\n            \n            // Send message to Node-RED\n            this.send({\n                payload: {\n                    [buttonName]: newState\n                },\n                timestamp: Date.now()\n            });\n        },\n        \n        getButtonStyle(buttonName, index) {\n            const size = this.config.size || '35px';\n            const border = this.config.border || 1;\n            const colors = this.config.color || {\n                active: '#2196F3',\n                inactive: '#FFFFFF',\n                hover: '#BBDEFB',\n                border: '#E0E0E0'\n            };\n            \n            const isActive = this.toggleStates[buttonName];\n            const isFirst = index === 0;\n            const isLast = index === this.buttons.length - 1;\n            \n            let backgroundColor = colors.inactive;\n            let textColor = '#666';\n            \n            if (isActive) {\n                backgroundColor = colors.active;\n                textColor = 'white';\n            }\n            \n            return {\n                width: size,\n                height: size,\n                backgroundColor: backgroundColor,\n                color: textColor,\n                border: `${border}px solid ${colors.border}`,\n                borderRight: isLast ? `${border}px solid ${colors.border}` : 'none',\n                borderRadius: '0',\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'center',\n                cursor: 'pointer',\n                transition: 'all 0.2s ease',\n                userSelect: 'none',\n                boxSizing: 'border-box'\n            };\n        },\n        \n        getIconClass(icon) {\n            return 'material-icons';\n        },\n        \n        getIconName(index) {                                                                                    // v1.1\n            return this.buttons[index].icon                                                                     // v1.1\n        },\n        \n        getTooltipText(buttonName) {\n            const button = this.buttons.find(b => b.name === buttonName);\n            return button ? button.tooltip : '';\n        },\n        \n        showTooltip(buttonName, event) {\n            this.tooltipVisible = buttonName;\n            \n            const rect = event.target.getBoundingClientRect();\n            this.tooltipStyle = {\n                position: 'fixed',\n                top: (rect.top - 35) + 'px',\n                left: (rect.left + rect.width / 2) + 'px',\n                transform: 'translateX(-50%)',\n                backgroundColor: 'rgba(0, 0, 0, 0.8)',\n                color: 'white',\n                padding: '6px 10px',\n                borderRadius: '4px',\n                fontSize: '12px',\n                whiteSpace: 'nowrap',\n                zIndex: 10001,\n                pointerEvents: 'none'\n            };\n        },\n        \n        hideTooltip() {\n            this.tooltipVisible = null;\n        }\n    },\n    \n    watch: {\n        msg: {\n            handler(newMsg) {\n                if (newMsg && newMsg.payload) {\n                    // Update states from incoming message\n                    Object.assign(this.toggleStates, newMsg.payload);\n                }\n                \n                if (newMsg && newMsg.config) {\n                    // Update configuration from incoming message\n                    Object.assign(this.config, newMsg.config);\n                }\n                \n                if (newMsg && newMsg.buttons) {\n                    // Update button definitions from incoming message\n                    this.buttons = newMsg.buttons;\n                    \n                    // Initialize states for new buttons\n                    newMsg.buttons.forEach(button => {\n                        if (!(button.name in this.toggleStates)) {\n                            this.$set(this.toggleStates, button.name, false);\n                        }\n                    });\n                }\n            },\n            deep: true\n        }\n    }\n}\n</script>\n\n<style scoped>\n.toggle-widget-container {\n    position: relative;\n    height: 100%;\n    width: 100%;\n}\n\n.toggle-button-group {\n    display: flex;\n    box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n}\n\n.toggle-btn {\n    transition: all 0.2s ease;\n}\n\n.toggle-btn:hover {\n    background-color: #BBDEFB !important;\n    z-index: 1;\n}\n\n.toggle-btn.active:hover {\n    background-color: #1976D2 !important;\n}\n\n.tooltip {\n    position: fixed;\n    background-color: rgba(0, 0, 0, 0.8);\n    color: white;\n    padding: 6px 10px;\n    border-radius: 4px;\n    font-size: 12px;\n    white-space: nowrap;\n    z-index: 10001;\n    pointer-events: none;\n}\n\n.material-icons {\n    font-size: 18px;\n    line-height: 1;\n}\n</style>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":1110,"y":1740,"wires":[["422345191feb1813"]],"info":"<template>\r\n    <div class=\"toggle-widget-container\">\r\n        <div :style=\"containerStyles\" class=\"toggle-button-group\">\r\n            <div \r\n                v-for=\"(button, index) in buttons\" \r\n                :key=\"button.name\"\r\n                :class=\"['toggle-btn', { \r\n                    'active': toggleStates[button.name], \r\n                    'first': index === 0, \r\n                    'last': index === buttons.length - 1 \r\n                }]\"\r\n                :style=\"getButtonStyle(button.name, index)\"\r\n                @click=\"toggleButton(button.name)\"\r\n                @mouseenter=\"showTooltip(button.name, $event)\"\r\n                @mouseleave=\"hideTooltip\"\r\n                :title=\"button.tooltip\"\r\n            >\r\n                <i :class=\"getIconClass(button.icon)\" class=\"material-icons\">{{ getIconName(button.icon) }}</i>\r\n                <v-icon class=\"material-icons\" >'mdi-hammer-screwdriver'</v-icon>\r\n            </div>\r\n        </div>\r\n        \r\n        <div v-if=\"tooltipVisible\" class=\"tooltip\" :style=\"tooltipStyle\">\r\n            {{ getTooltipText(tooltipVisible) }}\r\n        </div>\r\n    </div>\r\n</template>\r\n\r\n\r\n<script>\r\nexport default {\r\n    data() {\r\n        return {\r\n            toggleStates: {\r\n                'power': false,\r\n                'light': false,\r\n                'fan': false,\r\n                'settings': false\r\n            },\r\n            config: {\r\n                border: 1,\r\n                size: '35px',\r\n                position: 'bottom-right',\r\n                distance: 5,\r\n                color: {\r\n                    active: '#2196F3',\r\n                    inactive: '#FFFFFF',\r\n                    hover: '#BBDEFB',\r\n                    border: '#E0E0E0'\r\n                }\r\n            },\r\n            buttons: [\r\n                { name: 'config', icon: 'hammer-screwdriver', tooltip: 'cinfig' },\r\n                { name: 'charts', icon: 'chart-line', tooltip: 'charts' },\r\n                { name: 'temperature', icon: 'temperature-celsius', tooltip: 'Temperature Control' },\r\n                { name: 'humidifier', icon: 'air-humidifier', tooltip: 'humidifier Control' }\r\n            ],\r\n            tooltipVisible: null,\r\n            tooltipStyle: {}\r\n        };\r\n    },\r\n    computed: {\r\n        containerStyles() {\r\n            const pos = this.config.position || 'bottom-right';\r\n            const distance = `${this.config.distance || 5}px`;\r\n            \r\n            let positioning = {};\r\n            \r\n            if (pos.includes('bottom')) {\r\n                positioning.bottom = distance;\r\n            } else if (pos.includes('top')) {\r\n                positioning.top = distance;\r\n            }\r\n            \r\n            if (pos.includes('right')) {\r\n                positioning.right = distance;\r\n            } else if (pos.includes('left')) {\r\n                positioning.left = distance;\r\n            }\r\n            \r\n            return {\r\n                position: 'absolute',\r\n                display: 'flex',\r\n                zIndex: 1000,\r\n                ...positioning\r\n            };\r\n        }\r\n    },\r\n    methods: {\r\n        toggleButton(buttonName) {\r\n            const newState = !this.toggleStates[buttonName];\r\n            this.toggleStates[buttonName] = newState;\r\n            \r\n            // Send message to Node-RED\r\n            this.send({\r\n                payload: {\r\n                    [buttonName]: newState\r\n                },\r\n                timestamp: Date.now()\r\n            });\r\n        },\r\n        \r\n        getButtonStyle(buttonName, index) {\r\n            const size = this.config.size || '35px';\r\n            const border = this.config.border || 1;\r\n            const colors = this.config.color || {\r\n                active: '#2196F3',\r\n                inactive: '#FFFFFF',\r\n                hover: '#BBDEFB',\r\n                border: '#E0E0E0'\r\n            };\r\n            \r\n            const isActive = this.toggleStates[buttonName];\r\n            const isFirst = index === 0;\r\n            const isLast = index === this.buttons.length - 1;\r\n            \r\n            let backgroundColor = colors.inactive;\r\n            let textColor = '#666';\r\n            \r\n            if (isActive) {\r\n                backgroundColor = colors.active;\r\n                textColor = 'white';\r\n            }\r\n            \r\n            return {\r\n                width: size,\r\n                height: size,\r\n                backgroundColor: backgroundColor,\r\n                color: textColor,\r\n                border: `${border}px solid ${colors.border}`,\r\n                borderRight: isLast ? `${border}px solid ${colors.border}` : 'none',\r\n                borderRadius: '0',\r\n                display: 'flex',\r\n                alignItems: 'center',\r\n                justifyContent: 'center',\r\n                cursor: 'pointer',\r\n                transition: 'all 0.2s ease',\r\n                userSelect: 'none',\r\n                boxSizing: 'border-box'\r\n            };\r\n        },\r\n        \r\n        getIconClass(icon) {\r\n            return 'material-icons';\r\n        },\r\n        \r\n        getIconName(icon) {\r\n            return icon;\r\n        },\r\n        \r\n        getTooltipText(buttonName) {\r\n            const button = this.buttons.find(b => b.name === buttonName);\r\n            return button ? button.tooltip : '';\r\n        },\r\n        \r\n        showTooltip(buttonName, event) {\r\n            this.tooltipVisible = buttonName;\r\n            \r\n            const rect = event.target.getBoundingClientRect();\r\n            this.tooltipStyle = {\r\n                position: 'fixed',\r\n                top: (rect.top - 35) + 'px',\r\n                left: (rect.left + rect.width / 2) + 'px',\r\n                transform: 'translateX(-50%)',\r\n                backgroundColor: 'rgba(0, 0, 0, 0.8)',\r\n                color: 'white',\r\n                padding: '6px 10px',\r\n                borderRadius: '4px',\r\n                fontSize: '12px',\r\n                whiteSpace: 'nowrap',\r\n                zIndex: 10001,\r\n                pointerEvents: 'none'\r\n            };\r\n        },\r\n        \r\n        hideTooltip() {\r\n            this.tooltipVisible = null;\r\n        }\r\n    },\r\n    \r\n    watch: {\r\n        msg: {\r\n            handler(newMsg) {\r\n                if (newMsg && newMsg.payload) {\r\n                    // Update states from incoming message\r\n                    Object.assign(this.toggleStates, newMsg.payload);\r\n                }\r\n                \r\n                if (newMsg && newMsg.config) {\r\n                    // Update configuration from incoming message\r\n                    Object.assign(this.config, newMsg.config);\r\n                }\r\n                \r\n                if (newMsg && newMsg.buttons) {\r\n                    // Update button definitions from incoming message\r\n                    this.buttons = newMsg.buttons;\r\n                    \r\n                    // Initialize states for new buttons\r\n                    newMsg.buttons.forEach(button => {\r\n                        if (!(button.name in this.toggleStates)) {\r\n                            this.$set(this.toggleStates, button.name, false);\r\n                        }\r\n                    });\r\n                }\r\n            },\r\n            deep: true\r\n        }\r\n    }\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.toggle-widget-container {\r\n    position: relative;\r\n    height: 100%;\r\n    width: 100%;\r\n}\r\n\r\n.toggle-button-group {\r\n    display: flex;\r\n    box-shadow: 0 1px 3px rgba(0,0,0,0.1);\r\n}\r\n\r\n.toggle-btn {\r\n    transition: all 0.2s ease;\r\n}\r\n\r\n.toggle-btn:hover {\r\n    background-color: #BBDEFB !important;\r\n    z-index: 1;\r\n}\r\n\r\n.toggle-btn.active:hover {\r\n    background-color: #1976D2 !important;\r\n}\r\n\r\n.tooltip {\r\n    position: fixed;\r\n    background-color: rgba(0, 0, 0, 0.8);\r\n    color: white;\r\n    padding: 6px 10px;\r\n    border-radius: 4px;\r\n    font-size: 12px;\r\n    white-space: nowrap;\r\n    z-index: 10001;\r\n    pointer-events: none;\r\n}\r\n\r\n.material-icons {\r\n    font-size: 18px;\r\n    line-height: 1;\r\n}\r\n</style>"},{"id":"422345191feb1813","type":"debug","z":"506727cd93754bdb","name":"Toggle Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1330,"y":1740,"wires":[]},{"id":"b93577c7977b9d29","type":"ui-group","name":"Toggle Button","page":"b55c3e3640901741","width":6,"height":1,"order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"b55c3e3640901741","type":"ui-page","name":"Test Page","ui":"b810194ea14e3502","path":"/test","icon":"home","layout":"grid","theme":"5075a7d8e4947586","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":11,"className":"","visible":true,"disabled":false},{"id":"b810194ea14e3502","type":"ui-base","name":"Dashboard 2 Examples","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-control","ui-notification"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"default","titleBarStyle":"default","showReconnectNotification":true,"notificationDisplayTime":5,"showDisconnectNotification":true,"allowInstall":true},{"id":"5075a7d8e4947586","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"6px","groupBorderRadius":"4px","widgetGap":"12px","density":"default"}},{"id":"1582ab0dc5855460","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard":"1.26.0"}}]
1 Like

Thank you very much. I really messed up there. Now I'm getting somewhere.