Vue + Vuetify - Change v-col size depending on content - vue.js

In order to keep it simple i'm going to post a simplified version of what i need to do.
Assuming I've the following component
<template>
<div style="width: 50vw; height: 40vh;">
<v-container fluid>
<v-row style="background-color: #222222" class="fill-height">
<v-col cols="12" lg="8" xl="8" style="background-color: #ff0000"><h1>Breakpoint: {{$vuetify.breakpoint.name}}</h1></v-col>
<v-col cols="12" lg="4" xl="4" style="background-color: #00FF00"><v-img src="https://picsum.photos/256/256" min-height="256px" min-width="256px" max-height="256px" max-width="256px"/></v-col>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
}
</script>
Here is how it looks like on the browser:
Here is where it starts to break.
I need to have a responsive column that have a inside component with a fixed width and height.
Is there any thing that i can do to solve it?

If you don't specify a number of col widths for the first column it'll automatically try and use all the remaining space. cols="auto" can be used on the second column which will provide enough space for whatever content is inside. Together I believe they will accomplish your desired responsiveness. See this codesandbox as an example. Note the example also uses overflow-wrap: anywhere; on the h1 text to further prevent wrapping columns until absolutely necessary

Related

How to add image into v-text-field?

I have been trying to add image inside v-text-field, but it is causing an issue when I add it moves label to a bit of right side?
<v-text-field
ref="phone"
v-model="phone"
dense
outlined
disabled
color="black"
:rule="[requiredRule]"
:label="$t('10')"
>
<template #prepend-inner>
<v-img style="margin: auto 0" max-height="25" max-width="30" src="/images/KW.png"> </v-img>
</template>
</v-text-field>
as you can see label PHONE moves to right side it isn't staying on its place, I tried to add margin-top but didn't fix it.
This looks like an undocumented feature, which explains why the behaviour may be unexpected.
The cause of the seems to me is that the input calculates the width of the slot content at the time of rendering, which due to a race condition may resolve before or after the image is rendered. That's why if you render multiple times, you may not always see it behaving this way.
To get around it, I thing you should be able to wrap the image with another element of fixed width. (<div style="width:30px">)
<v-text-field
ref="phone"
v-model="phone"
dense
outlined
label="My Label"
>
<template #prepend-inner>
<div style="width:30px">
<v-img style="margin: auto 0" max-height="25" max-width="30" src="/images/KW.png"/>
</div>
</template>
</v-text-field>

Vuetify adaptative grid layout from item list

I have what seems to be a very common issue, but I can get over it.
I have an API query that returns me a list of object.
I want to display it my page as a grid of card filled with the content.
I want my grid to be in 5 column, and the number of row will adapt to the number of element in my list.
I can figure out how to achieve it.
For example: i have a query returning
items[
{"id":1,"title":"title1,"description":"description1"}
{"id":2,"title":"title2,"description":"description2"}
{"id":3,"title":"title3,"description":"description3"}
{"id":4,"title":"title4,"description":"description4"}
{"id":5,"title":"title5,"description":"description5"}
{"id":6,"title":"title6,"description":"description6"}
{"id":7,"title":"title7,"description":"description7"}
]
My grid as to be made from 7 elements with systematically 5 columns and adaptive rows like:
And if my query returns for example 14 elements, the layout should adapt to look like this:
The closest I was able to get with the code was.
<v-container class="mt-2">
<h1>Top Rated views</h1>
<v-row v-for="n in gridDivider" :key="n" class="n === 1 ? 'mb-6' : ''">
<v-col v-for="(item,index) in Items" :key="index">
<v-card class="mx-auto" max-width="300">
<v-img
class="white--text align-end"
height="200px"
src="item.avatar"
>
<v-card-title>anything as text</v-card-title>
</v-img>
<v-card-subtitle class="pb-0"> Number 10 </v-card-subtitle>
<v-card-text class="text--primary">
<div>Whitehaven Beach</div>
<div>Whitsunday Island, Whitsunday Islands</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
Thanks for helping
It could be done if you change v-row and v-col declarations this way:
<v-row class="five-cols">
<v-col v-for="(item,index) in Items" :key="index">
...
and create a CSS class five-cols using CSS Grid Layouts:
.five-cols {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
Example at CodePen

How to reduce the width of v-switch

The v-switch seems to always take 100% width, as seen below. Is there a way to reduce its clickable area to the minimum? Thanks!
clickable v-switch in the blank: https://vuetifyjs.com/en/components/switches/#usage
I suggest that you read this link from vuetify documentation. the reason that v-switch is continuing to the right of page is that v-container above it. you can modify the layout with vuetify grid system like below:
a Vue js page
<template>
<div class="about">
<v-container
class="px-0"
fluid
>
<v-row>
<v-col md="4">
<v-switch
class="my-border"
v-model="switch1"
:label="`Switch 1: ${switch1.toString()}`"
></v-switch>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
data () {
return {
switch1: true,
}
},
}
</script>
<style scoped>
.my-border {
border: 1px solid #000;
}
</style>
You can add d-inline-block class to v-switch which will reduce the div width to the content's max width.
The alternative, as the previous answer explained, is to wrap it in a row/column. Either don't set a column value or set it to a number because col-auto may cause it to be more narrow than desired and cause label to go over multiple lines.

Vuetify stop zoom out Website on small displays

I use Vuetify in my webapplication. The whole webapplication is responsive.
I have the problem that on smaller screens (Smartphone, Pad) I can zoom out of the website which means that I have a white space on the right of my website.
I don't know how this can happen and it is in every single page of my web application like that. What can I do that I use from beginning the whole space and the user can not zoom out from the website and gets this white space on the left?
Below a short example:
<template>
<v-app>
<v-main>
<v-container>
<v-row justify="center" align="center">
<v-col cols="12" xs="10" sm="10" md="10" lg="10" xl="10">
TEST_COL
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</template>
<script>
export default {
data: () => ({
}),
}
</script>
<style>
</style>
Maybe the problem is in the App.vue file but I don't see any problem there. To be sure I post the app.vue below:
<template>
<v-app>
<Navbar />
<v-main>
<router-view></router-view>
</v-main>
<Footer />
</v-app>
</template>
I put two screenshots below so you see what i mean.
Thanks!
Chris
I got the answer. I used the <v-navigation-drawer> provided by Vuetify to create a drawer object. I used the following options:
<v-navigation-drawer v-model="drawer" absolute temporary right>
But absolute means it "Applies position: absolute to the component." which means that it takes extra space in the website. The option must be "fixed" instead of "absolute" then it works.
The good settings are:
<v-navigation-drawer v-model="drawer" fixed temporary right>
Now the drawer opens on the right side of the website (better for smartphones) and it doesn't take any absolute space!!

CSS issues with Vuetify for responsivity using Vue-Split-Panel and select border

I'm having a variety of CSS issues with Vuetify that I'm hoping someone can help me resolve. I'm using a split panel view (vue-split-panel) with Vuetify, but Vuetify doesn't seem to consistently recognize when to trigger the full-column width, as shown below. I'm able to "trigger" the full column width (for the same split panel width) by just opening and then closing the Chrome js console.
I put this into a codesandbox so that it's reproducible. In doing so, I see a new issue that the radio buttons aren't showing.
https://codesandbox.io/s/split-view-test-7mlx1
If you're able to show me how to tweak the sandbox to make the responsivity work I'd so appreciate it!
Supposed to be a radio button:
Also, an issue that I can't reproduce in the codesandbox but I'm experiencing in my app (it's a JupyterLab extension) is shown in the bottom screenshot: the select label has the border line going through it. I tried to find if there is a CSS conflict somewhere but didn't know exactly where to look.
Furthermore I also have an issue that the select menu is offset proportional to the left menu, for some reason... why does opening the left and top menus effect the position? How can I fix it? I've tried using the "attach" property and adding an id to the element itself, or creating a parent div, but neither seems to solve it.
This is ~slightly reproducible in the sandbox by making the split panel wide and clicking the multi-select, then making it narrower and clicking again. You'll see that the menu is offset when it opens.
Solutions that don't involve iFrames would be preferred, and yes, I do have my app wrapped with <v-app>, however since it's a JupyterLab extension I only have access to the main tab space (not the left or top menus) so the v-app is wrapped around the HTML element which is the main tab area, not the full screen.
I think there might be a bug in the Vuetify code somewhere around this function: https://github.com/vuetifyjs/vuetify/blob/054555a42e2ef368df2d6e168d1eec7fc06fb12c/packages/vuetify/src/components/VSelect/VSelect.ts#L456
I have resolved all the CSS issues
Refactotred the grid layout by adding the proper components and breakdowns in UI. Added a fix to radio buttons. Added the css dependencies, material icons dependencies, fonts which vuetify uses internally
Check for the working codepen here: https://codesandbox.io/s/split-view-test-47f2h
<template>
<div id="app">
<v-app>
<Split style="height: 500px;">
<SplitArea :size="25">panel left</SplitArea>
<SplitArea :size="75">
<v-container fluid grid-list-md>
<v-layout row wrap>
<v-flex class="d-flex" xs="12" sm="12" md="6" lg="4">
<v-text-field
v-model="params.c.selected"
label="C"
hint="Penalty parameter C of the error term."
persistent-hint
return-object
type="number"
outlined
></v-text-field>
</v-flex>
<v-flex class="d-flex" sm="12" md="12" lg="6">
<v-select
v-model="params.kernel.selected"
hint="Specifies the kernel type to be used in the algorithm. It must be one of ‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’ or a callable. If none is given, ‘rbf’ will be used. If a callable is given it is used to pre-compute the kernel matrix from data matrices; that matrix should be an array of shape (n_samples, n_samples)."
:items="params.kernel.items"
label="Kernel"
persistent-hint
return-object
outlined
></v-select>
</v-flex>
<v-flex class="d-flex" sm="12" md="12" lg="6">
<v-text-field
v-model="params.degree.selected"
label="Degree"
hint="Degree of the polynomial kernel function ('poly'). Ignored by all other kernels."
persistent-hint
return-object
type="number"
outlined
></v-text-field>
</v-flex>
<v-flex class="d-flex" sm="12" md="12" lg="6">
<v-text-field
v-model="params.coef0.selected"
label="Coef0"
hint="Independent term in kernel function. It is only significant in 'poly' and 'sigmoid'."
persistent-hint
type="number"
outlined
></v-text-field>
</v-flex>
<v-flex class="d-flex" sm="12" md="12" lg="6">
<v-radio-group
v-model="params.probability.selected"
hint="Independent term in kernel function. It is only significant in 'poly' and 'sigmoid'."
persistent-hint
>
<template v-slot:label>
<div style="font-size: 12px">
Probability:
boolean, optional (default=False)
</div>
<br>
</template>
<v-radio label="True" :value="true" color="black"></v-radio>
<v-radio label="False" :value="false" color="black"></v-radio>
</v-radio-group>
</v-flex>
</v-layout>
</v-container>
</SplitArea>
</Split>
</v-app>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
params: {
c: { default: 1, selected: 1 },
kernel: {
default: "rbf",
selected: "rbf",
items: ["linear", "poly", "rbf", "sigmoid", "precomputed"]
},
degree: { default: 3, selected: 3 },
coef0: { defaul: 0.0, selected: 0.0 },
probability: { default: true, selected: true }
}
};
}
};
</script>
<style>
</style>