Vuetify v-date-picker formatting is wonky - how can I fix? - vue.js

v-date-picker formatting is screwy. The popup is chopped off at the bottom and there's a transparent gutter on the right hand side. Is this a known bug? The popup seems to always be the width of the container. I removed all CSS and simplified the app to the test below.
<!-- the layout (admin.vue) -->
<template>
<v-app>
<v-main>
<Nuxt class="ma-2"/>
</v-main>
</v-app>
</template>
<!-- the page -->
<template>
<div>
<v-menu :close-on-content-click="true" :nudge-right="40" transition="scale-transition" offset-y>
<template v-slot:activator="{ on }">
<v-text-field label="Date listed" prepend-icon="mdi-calendar" :value="form.dateListed" v-on="on"/>
</template>
<v-date-picker v-model.lazy="form.dateListed" locale="en-us" header-color="primary" tabindex="0"/>
</v-menu>
</div>
</template>
<script>
export default {
layout: 'admin',
data() {
return {
form: {
},
}
},
}
</script>
enter image description here

You need to add min-width: auto to the v-menu like this:
<v-menu min-width="auto" v-model="menus.date">
...
</v-menu>

Related

Vuetify grid system issues in Nuxt across layouts, pages and components (+ background color issue)

I am trying to replicate this login page layout: Mentor Cruise Login Page
Basically a 1/3 vs 2/3 split and a vertically centered login component.
I'm using my default.vue layout to manage whether or not the navbar/appbar are shown at all. Also use middleware to redirect to the authentication.vue page if no user is present. The logic all works. But the layout has me struggling. The Vuetify documentation is spotty or assumes lots of CSS knowledge I don't have. I tried reading up on CSS flexbox but it does not seem to translate as I would expect or maybe Nuxt is getting in the way with the parent-child relationship handling between layouts, pages and components.
If someone could let me know how I can recreate this layout and where this should go, that would be great!
Here are the elements that should create this top-down:
default.vue layout file:
<template>
<v-app id="youtu.be/dQw4w9WgXcQ">
<template v-if="isLoggedIn">
<Navbar />
<Snackbar />
<Confirm />
</template>
<v-main>
<Nuxt />
</v-main>
<Footer />
</v-app>
</template>
authentication.vue page file
<template>
<v-container id="authentication">
<v-row no-gutters fluid align="center">
<v-col cols="4" class="info">
<v-img
:src="require('~/assets/XXX.png')"
contain
max-height="100"
max-width="100"
></v-img>
</v-col>
<v-col cols="8">
<client-only>
<Login />
</client-only>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
head() {
return {
title: this.title,
}
},
data: () => ({
title: 'Authentication',
}),
}
</script>
<style scoped>
.theme--dark.v-application {
background-color: var(--v-background-base, #121212) !important;
}
.theme--light.v-application {
background-color: var(--v-background-base, white) !important;
}
</style>
Login.vue component
<template>
<v-container>
<v-row justify="center" align="center">
<v-col cols="12" sm="8" md="6">
<v-card>
<v-card-title class="headline">
<span v-if="this.isLoggedIn">Welcome {{ this.displayName }}</span>
</v-card-title>
<v-card-text>
<div v-if="!this.isLoggedIn">
<div id="firebaseui-auth-container"></div>
</div>
<div v-else>
<p>You are logged in with {{ this.email }}.</p>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
const { mapGetters } = createNamespacedHelpers('user')
export default {
name: 'Login',
mounted() {
//firebaseUi stuff that works
},
computed: {
...mapGetters({
isLoggedIn: 'getIsLoggedIn',
displayName: 'getUserDisplayName',
email: 'getUserEmail',
}),
},
}
</script>
What I have:
What I have (Console):
What I want:
If someone can then tell me how the hell I set the col background color using the vuetify theme config from nuxt.config.js that would be amazing. I tried classes, I tried the color prop..nothing works.
// Edit1: Added console/CSS screenshot as per #kissu's request
// Edit2: Added codepen
Solved this in a hackey way by wrapping the elements contained in the 2 columns in a container again. I DO NOT think this is how you should do it. Probably upsetting the CSS gods. But it works.
<v-container id="authentication" fluid fill-height pa-0>
<v-row no-gutters style="height: 100%" id="authentication-row">
<v-col cols="4" class="primary darken-2">
<v-container fluid fill-height justify-center>
<v-img
:src="require('~/assets/logo.png')"
contain
max-height="100"
max-width="100"
></v-img>
</v-container>
</v-col>
<v-col cols="8">
<v-container fluid fill-height justify-center>
<client-only>
FirebaseUI component
</client-only>
</v-container>
</v-col>
</v-row>
</v-container>

How to make v-skeleton-loader inside v-for in vuetify?

I am trying to show a v-skeleton-loader in Vuetify. I have used v-if and v-else. If the image is not loaded, then it should show the skeleton loader. Otherwise, it should should show the image. This is my code:
<template>
<v-col v-for="option in options" :key="option.id" cols="6">
<v-lazy :options="{ threshold: 0.5 }" min-height="130">
<v-hover v-slot="{ hover }">
<v-card id="options_card" link width="160">
<v-sheet v-if="!images" class="px-3 pt-3 pb-3">
<v-skeleton-loader max-width="300" type="image"></v-skeleton-loader>
</v-sheet>
<v-img
v-else
id="thumbnail"
width="100%"
height="130"
:src="option.thumbnail"
></v-img>
</v-card>
</v-hover>
</v-lazy>
</v-col>
</template>
<script>
export default {
data() {
return {
images: false,
}
},
mounted() {
this.images = true
},
}
</script>
But the v-skeleton-loader is not seen on the screen.
VImage has a placeholder slot that would be used for customizing the loader component to be shown while the image is loading:
<v-img>
<template v-slot:placeholder>
<v-sheet>
<v-skeleton-loader />
</v-sheet>
</template>
</v-img>
demo
<v-img>
<template v-slot:placeholder>
<v-sheet>
<v-skeleton-loader />
</v-sheet>
</template>
</v-img>

How to use router-link "to" prop on vuetify components?

I have an avatar image, upon click I'd like to route to one of my paths. I understand I can do it with router-view, but also that vuetify inherits its properties.
What is missing?:
<div id="app">
<v-app>
<v-app-bar>
<v-toolbar-items>
<v-avatar to="'/profile'">
<v-img src="http://www.dumpaday.com/wp-content/uploads/2019/10/00-156-750x280.jpg"></v-img>
</v-avatar>
</v-toolbar-items>
</v-app-bar>
</v-app>
</div>
full example:
https://codepen.io/toit123/pen/GRRmpqq
v-avatar isn't a link abd doesn't support to so you have to wrap your image with a router link like:
<div id="app">
<v-app>
<v-app-bar>
<v-toolbar-items>
<router-link to="/profile">
<v-avatar>
<v-img src="http://www.dumpaday.com/wp-content/uploads/2019/10/00-156-750x280.jpg"></v-img>
</v-avatar>
</router-link>
</v-toolbar-items>
</v-app-bar>
</v-app>
</div>
Or you add a custom click event on the v-avatar and do the routing in a method like
<v-avatar #click="forward">
JS
methods: {
forward() {
this.$router.push("/profile")
}
}

Using v-tooltip inside v-menu activator in vuetify 2.0

How to use v-tooltip inside v-menu activator with vuetify 2.0? Previously it was working using slot="activator".
That's what I'm trying to combine:
<v-menu>
<template v-slot:activator="{on}">
<v-btn v-on="on">Menu Trigger</v-btn>
</template>
...list with menu options...
</v-menu>
and
<v-tooltip v-slot:activator="{on}">
<v-btn v-on="on">Menu Trigger with Tooltip</v-btn>
<span>Tooltip Content</span>
</v-tooltip>
Now I try to paste v-tooltip inside v-menu, what should happen with {on} here?
I think you're most likely unsure about the "conflicted" on objects passed to the template by multiple activator slots and how to apply all of the event handlers on the target element(s).
If that's the case, you can workaround this by assigning either one (or both) of them to a variable with a different name (see: assigning to new variable names), and then destructure and "restructure", which basically glues them back together (or merge them, technically speaking).
<v-menu>
<template #activator="{ on: onMenu }">
<v-btn v-on="onMenu">Menu Trigger</v-btn>
<v-tooltip bottom>
<template #activator="{ on: onTooltip }">
<v-btn v-on="{ ...onMenu, ...onTooltip }">Menu Trigger with Tooltip</v-btn>
</template>
<span>Tooltip Content</span>
</v-tooltip>
</template>
<!-- ...list with menu options... -->
</v-menu>
Or, use the slot props directly. Just make sure to name them properly so they won't introduce another naming conflict with the component's data and/or props.
<v-menu>
<template #activator="menu">
<v-btn v-on="menu.on">Menu Trigger</v-btn>
<v-tooltip bottom>
<template #activator="tooltip">
<v-btn v-on="{ ...menu.on, ...tooltip.on }">Menu Trigger with Tooltip</v-btn>
</template>
<span>Tooltip Content</span>
</v-tooltip>
</template>
<!-- ...list with menu options... -->
</v-menu>
Complete Demo:
new Vue({
el: '#app',
data: () => ({
items: [
{ title: 'Item #1' },
{ title: 'Item #2' },
{ title: 'Item #3' }
]
})
})
<link href="https://fonts.googleapis.com/css?family=Roboto:400|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.x/dist/vuetify.js"></script>
<div id="app">
<v-menu>
<template #activator="{ on: onMenu }">
<v-btn v-on="onMenu">Menu Trigger</v-btn>
<v-tooltip bottom>
<template #activator="{ on: onTooltip }">
<v-btn v-on="{ ...onMenu, ...onTooltip }">Menu Trigger with Tooltip</v-btn>
</template>
<span>Tooltip Content</span>
</v-tooltip>
</template>
<v-list>
<v-list-tile
v-for="(item, index) in items" :key="index"
#click.prevent>
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>

How can i pass background color as Prop in for loop?

its me again!
so i have a own component:
<template>
<div class='mynewcomponent'>
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-card v-bind:style="{ backgroundColor: this.myColor}">
<!-- Picture
<v-img
src="https://cdn.vuetifyjs.com/images/cards/sunshine.jpg"
height="200px"
>
</v-img>
-->
<v-card-title primary-title>
<div>
<slot name="header">Top western road trips</slot>
<br>
<slot name="TestDesciption">1,000 miles of wonder</slot>
</div>
</v-card-title>
<v-card-actions>
<v-btn flat>Share</v-btn>
<v-btn flat color="purple">Explore</v-btn>
<v-spacer></v-spacer>
<v-btn icon #click="show = !show">
<v-icon>{{ show ? 'keyboard_arrow_down' : 'keyboard_arrow_up' }}</v-icon>
</v-btn>
</v-card-actions>
<v-slide-y-transition>
<v-card-text v-show="show">
I'm a thing. But, like most politicians, he promised more than he could deliver. You won't have time for sleeping, soldier, not with all the bed making you'll be doing. Then we'll go with that data file! Hey, you add a one and two zeros to that or we walk! You're going to do his laundry? I've got to find a way to escape.
</v-card-text>
</v-slide-y-transition>
</v-card>
</v-flex>
</v-layout>
</div>
</template>
<script>
export default {
data: () => ({
show: false,
myColor:'#ffffff'
})
}
</script>
and in my about.vue i load it in a for loop:
<template>
<div class='about'>
<mynewcomponent v-for="(item,index) in 100"/>>
<template v-slot:header>
<h3 style="text-align: left;"><span style="color: #3366ff">ID: 1234</span></h3>
</template>
<template v-slot:TestDesciption>
<h3 style="text-align: left">example shit</h3>
</template>
</mynewcomponent>
</div>
</template>
<script>
import myNewComponent from '#/components/myNewComponent.vue'; // # is an alias to /src
export default {
name: 'about',
components: {
'mynewcomponent': myNewComponent
}
}
</script>
now i want the even and odd Cards in other background color.
i tried everything what google says but whitout success.
i will pass the color if index % 2 == 0 (even or odd)
how can i pass the color in the for loop ?
or can someone tell me a better way to do this?
Thank you
You can create a method to bind the class attribute and pass the index as a parameter. For each line, you can evaluate and return a different class to this element.
You can check am example here
methods:{
spanClass: function(index) {
return {
in: index % 2 === 0,
out: index % 2 !== 0
}
}
li.in {
background-color:red;
}
li.out {
background-color:black;
}
<template>
<div class='about'>
<mynewcomponent v-for="(item,index) in 100"/>>
<template v-slot:header>
<h3 style="text-align: left;"><span :class="spanClass(item)">ID: 1234</span></h3>
</template>
<template v-slot:TestDesciption>
<h3 style="text-align: left">example shit</h3>
</template>
</mynewcomponent>
</div>
</template>