2 cups of tea if you please
If to create it as for dedicated use, it is possible to use container query and change the layout quite a lot.
But for common usage the outcome may be not so pleasant. Query may be clever but the break point depends on states you have configured - character count, if icons .... So it is not predictable.
Something to play with:
<template>
<div :style="`--container:${container};`" class="mss-widget">
<div class="mss-wrapper">
<header>
{{label}}
</header>
<v-btn-toggle mandatory divided rounded="xl" :variant="variant" :color="selectedColor" v-model="selection">
<v-btn v-for="(option, index) in options" :key='index' :class="option.label ? '' : 'icon-only'">
<template v-if="option.icon" v-slot:prepend>
<v-icon size="x-large"> {{option.icon}} </v-icon>
</template>
{{option.label}}
</v-btn>
</v-btn-toggle>
</div>
</div>
</template>
<script>
export default {
data() {
return {
//define me here
label:"Multistate Prototype",
options:[
{label:"first",value:"first",icon:"mdi-basketball",color:"green"},
{label:"second", value:"second", icon:"mdi-basketball",color:"red"},
/* {label:"1",value:1, color:"blue",icon:"mdi-car-wrench"},
{label:"2", value:2, color:"orange",icon:"mdi-car-wrench"},*/
{label:"TRUE FALSE",value:true,color:"green"},
{label:"false",value:false,icon:"mdi-antenna",color:"green"}
],
// "outlined" (if the site bg is white or very light)"
// "default" (if the site bg is dark)"
// ("text" or "plain" also available but requires some styling)
look:"outlined",
container:"four",//name for container query (four and six available, different break points)
// no need to change those
selection: null,
changeByInput:false, // in case of input - render but don't send the msg out
}
},
watch: {
msg: function(){
if(this.isValidValue(this.msg.payload)){
this.changeByInput = true
this.selection = this.options.findIndex(option => option.value === this.msg.payload )
}
},
selection:function(){
if(this.changeByInput == true){
this.changeByInput = false
}
else{
this.send(this.getOutputMessage())
}
}
},
methods: {
isValidValue:function (val){
if(val === null){
return false
}
if(val === undefined){
return false
}
if(val === ""){
return false
}
if(!['number', 'string', 'boolean'].includes(typeof value)){
return false
}
if(this.options.findIndex(option => option.value === val ) == -1){
return false
}
return true
},
findOptionByValue:function(val){
let opt = this.options.find(option => option.value === val)
if(opt){
return opt
}
return null
},
getOutputMessage:function(){
return {payload:this.options[this.selection].value,topic:'multistate'}
}
},
computed: {
selectedColor:function(){
if(this.selection == null){
return ""
}
return this.options[this.selection].color ?? "rgb(var(--v-theme-primary))"
},
variant:function(){
return this.look == "default" ? null : this.look
}
}
}
</script>
<style>
.mss-widget{
container-type:inline-size;
container-name:var(--container);
}
.mss-wrapper {
display:grid;
grid-template-columns:1fr 1fr;
align-items:center;
}
.mss-wrapper header{
white-space:normal;
padding-right:var(--layout-gap);
}
.mss-wrapper header i{
display:none;
}
.mss-wrapper .v-chip.v-chip--size-default{
padding:0;
}
.mss-wrapper .v-btn-group{
width:max-content;
border-color:rgba(var(--v-border-color),.3);
}
.mss-wrapper .v-btn--variant-elevated, .mss-wrapper .v-btn--variant-outlined{
color:#cccccc;
}
.mss-wrapper .icon-only .v-btn__prepend{
margin-inline:0;
}
@container four (max-width: 500px){
.mss-wrapper {
grid-template-columns:none;
grid-template-rows:1fr 2fr;
align-items:center;
justify-content:center;
text-align:center;
}
.mss-wrapper .v-btn__prepend{
margin-inline:0;
}
.mss-wrapper .v-btn__content{
white-space: normal;
max-width: min-content;
}
.mss-wrapper .v-btn:has(.v-btn__prepend) .v-btn__content{
display:none;
}
}
@container six (max-width: 650px){
.mss-wrapper {
grid-template-columns:none;
grid-template-rows:1fr 2fr;
align-items:center;
justify-content:center;
text-align:center;
}
.mss-wrapper .v-btn__prepend{
margin-inline:0;
}
.mss-wrapper .v-btn__content{
white-space: normal;
max-width: min-content;
}
.mss-wrapper .v-btn:has(.v-btn__prepend) .v-btn__content{
display:none;
}
}
</style>
And if you like to have something stronger than tea:
Hi, I have problem, I configured 12 states for my multistate switch with nice long names and icons. Can you figure out why it doesn't fit into my mobile screen