A little bit of fun with sliders
[{"id":"1c0c26f3ab8a24c8","type":"ui-template","z":"e59576a114c1e493","group":"6f47b8907c5da63a","page":"","ui":"","name":"range","order":5,"width":"6","height":"1","head":"","format":"<template>\n <v-range-slider class=\"range-slider\" v-model=\"value\" step=\"1\" thumb-label=\"true\" show-ticks=\"always\" :ticks=\"tickLabels\" :messages=\"advise\">\n <template v-slot:append>\n <v-chip v-model=\"value\">\n Range: <span>{{rangeValue}}</span>\n </v-chip>\n </template>\n </v-range-slider>\n</template>\n\n<script>\n export default {\n data() {\n return {\n min:0,\n max:100,\n value: [0, 100],\n fromServer:false,\n tickLabels: {\n 0: '0',\n 10: '10',\n 20: '20',\n 30: '30',\n 40: '40',\n 50: '50',\n 60: '60',\n 70: '70',\n 80: '80',\n 90: '90',\n 100: '100', \n },\n \n }\n },\n watch: { \n value:function(){\n if(this.fromServer == true){\n this.fromServer = false;\n return\n }\n this.send({payload:{min:this.value[0],max:this.value[1]}})\n },\n msg: function(){ \n if(this.msg.payload !== undefined){\n this.fromServer = true; \n this.value = [this.msg.payload.min,this.msg.payload.max]\n }\n },\n },\n computed: {\n rangeValue: function(){\n return (this.value[1] - this.value[0]).toString() \n },\n advise:function(){\n const r = this.value[1] - this.value[0]\n if(this.value[0] == this.value[1] && this.value[1] == 0){\n return \"Please select range\"\n }\n if(r == 0){\n return \"No range\"\n }\n if(r < 10){\n return \"Too small range\"\n }\n if(r > 90){\n return \"Are you sure?\"\n }\n return \"\"\n }\n },\n }\n</script>\n<style>\n .range-slider {\n color:rgb(var(--v-theme-primary));\n }\n .range-slider.v-input--horizontal {\n grid-template-areas:\"a b messages\" \"prepend control append\";\n grid-template-columns: max-content minmax(0, 1fr) max-content;\n grid-template-rows: auto auto;\n }\n .range-slider .v-input__details{\n min-heigth:20px;\n }\n .range-slider .v-slider-track__tick-label { \n font-size: .75rem;\n }\n .range-slider i{\n color:currentColor;\n }\n .range-slider .v-slider-thumb__surface:before {\n background-color:rgb(var(--v-theme-primary));\n }\n .range-slider .v-chip__content span { \n font-size: large;\n font-weight: 600; \n min-width: 3.2ch;\n text-align: end;\n }\n .range-slider .v-locale--is-ltr.v-slider.v-input--horizontal .v-slider-track__tick--last .v-slider-track__tick-label, .v-locale--is-ltr .v-slider.v-input--horizontal .v-slider-track__tick--last .v-slider-track__tick-label {\n transform: translate(-50%); \n }\n .range-slider .v-slider-thumb__label {\n background: rgba(var(--v-theme-primary), .6);\n color: rgb(var(--v-theme-on-primary));\n }\n .range-slider .v-slider-thumb__label:before {\n color: rgba(var(--v-theme-primary), .6);\n }\n .range-slider .v-messages{\n text-align:center;\n }\n</style>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":370,"y":100,"wires":[["81b839ebcfea2eda"]]},{"id":"81b839ebcfea2eda","type":"debug","z":"e59576a114c1e493","name":"Range","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":100,"wires":[]},{"id":"db354eee1821fe90","type":"inject","z":"e59576a114c1e493","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"min\":50,\"max\":80}","payloadType":"json","x":190,"y":100,"wires":[["1c0c26f3ab8a24c8"]]},{"id":"7cca73e94c749a03","type":"ui-template","z":"e59576a114c1e493","group":"6f47b8907c5da63a","name":"mixer","order":6,"width":"6","height":"1","head":"","format":"<template>\n <div class=\"mixer-wrapper\">\n <div v-for=\"channel in mixer\" :key=\"channel.name\" class=\"mixer-channel\"> \n <v-slider\n v-model=\"channel.value\"\n :label=\"channel.name\"\n direction=\"vertical\"\n step=\"0.5\" \n thumb-label=\"true\"\n show-ticks=\"always\"\n :ticks=\"tickLabels\"\n :disabled=\"channel.disabled\" \n @end=\"onChange(channel)\" \n > \n <template v-slot:append v-model=\"channel.value\">\n <v-chip>\n {{channel.value.toFixed(1)}}\n </v-chip>\n </template> \n </v-slider>\n \n <v-btn v-model=\"channel.disabled\" icon @click=\"onMute(channel)\" elevation=\"1\">\n <v-icon v-if=\"channel.disabled\">mdi-scent-off</v-icon>\n <v-icon v-else>mdi-scent</v-icon>\n </v-btn>\n </div> \n </div>\n</template>\n\n<script>\n export default {\n data() {\n // define variables available component-wide\n // (in <template> and component functions)\n return { \n mixer:[\n {name:\"Line 1\",value:0,lastValue:0,disabled:false},\n {name:\"Line 2\",value:0,lastValue:0,disabled:false},\n {name:\"Line 3\",value:0,lastValue:0,disabled:false},\n {name:\"Line 4\",value:0,lastValue:0,disabled:false},\n {name:\"Line 5\",value:0,lastValue:0,disabled:false},\n {name:\"Line 6\",value:0,lastValue:0,disabled:false}\n ],\n tickLabels: {\n 0: '0',\n 10: '10',\n 20: '20',\n 30: '30',\n 40: '40',\n 50: '50',\n 60: '60',\n 70: '70',\n 80: '80',\n 90: '90',\n 100: '100', \n },\n \n \n }\n },\n watch: { \n msg: function(){ \n if(this.msg.payload != undefined) { \n this.mixer = this.msg.payload\n }\n } \n },\n computed: { \n },\n methods: {\n onMute:function(channel){\n if(!channel.disabled){\n channel.lastValue = channel.value\n }\n channel.disabled = !channel.disabled;\n channel.value = channel.disabled ? 0 : channel.lastValue\n this.onChange(channel)\n },\n onChange:function(c) { \n this.send({payload:this.mixer,changed:c})\n },\n \n },\n mounted() { \n },\n unmounted() { \n }\n }\n</script>\n<style>\n /* define any styles here - supports raw CSS */\n .mixer-wrapper{\n display:grid; \n grid-template-columns: repeat(auto-fit, 85px);\n justify-content: space-evenly; \n outline: 1px solid rgba(var(--v-theme-primary),0.4);\n border-radius: .125rem;\n padding: .25rem; \n }\n .mixer-wrapper .mixer-channel {\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n .mixer-wrapper .v-slider.v-input--vertical>.v-input__control{\n min-height:200px;\n }\n .mixer-wrapper .v-slider__label{\n margin-inline:0;\n }\n .mixer-wrapper .v-chip__content{\n justify-content:center; \n font-size: large;\n font-weight: 600; \n min-width: 4.5ch;\n text-align:center;\n padding:0; \n }\n .mixer-wrapper .v-slider.v-input--vertical {\n color:rgb(var(--v-theme-primary));\n margin-block-end: 0;\n }\n .mixer-wrapper .v-input__details{\n display:none;\n }\n .mixer-wrapper .v-input__prepend{\n justify-content:center;\n }\n .mixer-wrapper .v-slider.v-input--vertical .v-slider-track__tick{\n width:20px;\n height:1px; \n transform: translate(-50%,0);\n background:rgba(var(--v-theme-primary),0.4);\n }\n .mixer-wrapper .v-slider.v-input--vertical .v-slider-track__tick .v-slider-track__tick-label {\n \n transform: translateY(-50%);\n text-align: center;\n width: 30px;\n margin-inline-start: unset;\n left: -30px;\n font-size: x-small;\n }\n .mixer-wrapper .v-slider-thumb__label {\n background: rgba(var(--v-theme-primary), .6);\n color: rgb(var(--v-theme-on-primary));\n }\n .mixer-wrapper .v-slider-thumb__label:before {\n color: rgba(var(--v-theme-primary), .6);\n }\n .mixer-wrapper .v-btn.v-btn--density-default{\n min-width:unset;\n min-height:unset;\n width:35px;\n aspect-ratio:1;\n color: rgba(var(--v-theme-primary), .6);\n background: rgb(var(--v-theme-on-primary));\n \n }\n \n \n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":370,"y":160,"wires":[["b0c6f0b9198e061c"]]},{"id":"b0c6f0b9198e061c","type":"debug","z":"e59576a114c1e493","name":"MIXER","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":520,"y":160,"wires":[]},{"id":"56fa38f41302946d","type":"comment","z":"e59576a114c1e493","name":"msg.payload for Mixer ","info":"msg.payload (an array) for Mixer should contain \nfull set of data. \n\nmsg.payload = [\n {\"name\":\"Line 1\",\"value\":29,\"lastValue\":29,\"disabled\":false},\n {\"name\":\"Line 2\",\"value\":72.5,\"lastValue\":28.5,\"disabled\":false},\n {\"name\":\"Line 3\",\"value\":55,\"lastValue\":35,\"disabled\":false},\n {\"name\":\"Line 4\",\"value\":67.5,\"lastValue\":33.5,\"disabled\":false},\n {\"name\":\"Line 5\",\"value\":34.5,\"lastValue\":34.5,\"disabled\":false},\n {\"name\":\"Line 6\",\"value\":51.5,\"lastValue\":51.5,\"disabled\":false}\n]\n","x":180,"y":160,"wires":[]},{"id":"6f47b8907c5da63a","type":"ui-group","name":"Sliders","page":"19eb6d108e9275e2","width":"6","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"19eb6d108e9275e2","type":"ui-page","name":"Examples","ui":"ae3d4aeb3f977a90","path":"/examples","icon":"","layout":"grid","theme":"a965ccfef139317a","order":2,"className":"","visible":true,"disabled":"false"},{"id":"ae3d4aeb3f977a90","type":"ui-base","name":"Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"navigationStyle":"icon","titleBarStyle":"default"},{"id":"a965ccfef139317a","type":"ui-theme","name":"Default","colors":{"surface":"#ffffff","primary":"#338109","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]