I'm new to vuetify.
I use Vuetify v-list sample (Github)
My v-list:
Code:
<template>
<v-card
max-width="500"
class="mx-auto"
>
<v-toolbar
color="pink"
dark
>
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>Inbox</v-toolbar-title>
</v-toolbar>
<v-list two-line>
<v-list-item-group
v-model="selected"
multiple
active-class="pink--text"
>
<template v-for="(item, index) in items">
<v-list-item :key="item.title">
<template v-slot:default="{ active, toggle }">
<v-list-item-content>
<v-list-item-title v-text="item.title"></v-list-item-title>
<v-list-item-subtitle class="text--primary" v-text="item.headline"></v-list-item-subtitle>
<v-list-item-subtitle v-text="item.subtitle"></v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-list-item-action-text v-text="item.action"></v-list-item-action-text>
</v-list-item-action>
</template>
</v-list-item>
<v-divider
v-if="index + 1 < items.length"
:key="index"
></v-divider>
</template>
</v-list-item-group>
</v-list>
</v-card>
</template>
<script>
export default {
data: () => ({
selected: [2],
items: [
{
action: '15 min',
headline: 'Brunch this weekend?',
title: 'Ali Connors',
subtitle: "I'll be in your neighborhood doing errands this weekend. Do you want to hang out?",
},
{
action: '2 hr',
headline: 'Summer BBQ',
title: 'me, Scrott, Jennifer',
subtitle: "Wish I could come, but I'm out of town this weekend.",
},
{
action: '6 hr',
headline: 'Oui oui',
title: 'Sandra Adams',
subtitle: 'Do you have Paris recommendations? Have you ever been?',
},
{
action: '12 hr',
headline: 'Birthday gift',
title: 'Trevor Hansen',
subtitle: 'Have any ideas about what we should get Heidi for her birthday?',
},
{
action: '18hr',
headline: 'Recipe to try',
title: 'Britta Holt',
subtitle: 'We should eat this: Grate, Squash, Corn, and tomatillo Tacos.',
},
],
}),
}
</script>
I want when I hover on each v-list-item, A light white background with some shadow a button in it's center to be appeared. (I made this hover concept in Photoshop):
Should I use v-hover component? And what style should I use?
Thanks.
Use v-hover and v-overlay...
<v-list two-line>
<v-list-item-group v-model="selected" multiple active-class="pink--text">
<template v-for="(item, index) in items">
<v-hover v-slot:default="{ hover }">
<v-list-item :key="item.title">
<template v-slot:default="{ active, toggle }">
<v-expand-transition>
<v-overlay
absolute
:opacity=".2"
:value="hover"
>
<v-btn
color="white"
class="black--text"
>
Button
</v-btn>
</v-overlay>
</v-expand-transition>
<v-list-item-content>
<v-list-item-title v-text="item.title"></v-list-item-title>
<v-list-item-subtitle class="text--primary" v-text="item.headline"></v-list-item-subtitle>
<v-list-item-subtitle v-text="item.subtitle"></v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-list-item-action-text v-text="item.action"></v-list-item-action-text>
</v-list-item-action>
</template>
</v-list-item>
</v-hover>
<v-divider v-if="index + 1 < items.length" :key="index"></v-divider>
</template>
</v-list-item-group>
</v-list>
Demo: https://codeply.com/p/16POCG8AKf
Related
I created a project in stable Nuxtjs3 with vuetify3 templating framework. I can set prepend icon or inner icon nothing is displayed, with mdi or font awesome.
No error in console, no error in server. I just want to add icons on input form
<template>
<div>
<v-app id="inspire">
<v-container fluid fill-height>
<v-row vertical-align="center">
<v-col lg="6" sm="12" align-self="center" offset-lg="3">
<v-card class="elevation-12">
<v-toolbar dark color="success">
<v-toolbar-title>Se connecter</v-toolbar-title>
</v-toolbar>
<v-card-text>
<Form as="v-form" #submit="onSubmit" :validation-schema="schema" >
<Field name="username" v-slot="{ field, errors }">
<v-text-field
label="Login"
type="email"
v-bind="field"
variant="solo"
append-inner-icon="mdi-magnify"
:error-messages="errors"
></v-text-field>
</Field>
<Field name="password" v-slot="{ field, errors }">
<v-text-field
id="password"
prepend-inner-icon="fa:fas fa-lock"
label="Password"
type="password"
v-bind="field"
variant="solo"
:error-messages="errors"
></v-text-field>
</Field>
<v-btn
block
color="success"
size="large"
type="submit"
>
Se connecter
</v-btn>
</Form>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
nuxt js config
// https://v3.nuxtjs.org/api/configuration/nuxt.config
// #ts-ignore
export default defineNuxtConfig({
runtimeConfig: {
SECRET: '',
public: {
REST_API_URL: process.env.NUXT_REST_API_URL || 'http://localhost:8089/api',
SUPER_ADMIN_ROLE: 'SUPER_ADMIN',
KITCHEN_ROLE:'',
DELIVERY_ROLE:'',
CASHIER_ROLE:''
}
},
css: [
"vuetify/lib/styles/main.sass"
],
build: {
transpile: ["vuetify"]
},
vite: {
define: {
"process.env.DEBUG": false
}
}
})
and vuetify.js in plugins
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
components
})
nuxtApp.vueApp.use(vuetify)
})
the display is the following
and in DOM
Any idea ?
thanks to this link question
npm install import #mdi/font
Then in your nuxt.config.js add the following entry to your css field:
css: ["#mdi/font/css/materialdesignicons.css"]
so for me:
css: [
"vuetify/lib/styles/main.sass","#mdi/font/css/materialdesignicons.css"
],
and it is ok
I have a Vuetify project. I'm using the template with a slot group.header, so far so good.
Now I want to use a <v-spacer> in this template. Its in a <v-sheet>.
When I use the <v-spacer></v-spacer> I expect the content on the same line. But it will be on the next line. How can I display the button after the spacing on the same line, user Vuetify's system?
codepen
https://codepen.io/h3ll/pen/VwWOxdJ?editors=1010
HTML
<v-data-table
:headers="headers"
:items="desserts"
item-key="name"
sort-by="name"
group-by="category"
class="elevation-1"
show-group-by
>
<template v-slot:group.header="{items, isOpen, toggle}">
<th #click="toggle" colspan="12" class="ma-0 pa-0">
<v-sheet>
<v-icon class="mr-3">{{ isOpen ? 'mdi-folder-open' : 'mdi-folder' }}</v-icon>
{{ items[0].category }}
<v-spacer></v-spacer>
<v-btn x-small>I WANT TO BE ON THE RIGHT SIDE</v-btn>
</v-sheet>
</th>
</template>
</v-data-table>
javascript
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: 'Dessert (100g serving)',
align: 'start',
value: 'name',
groupable: false,
},
{ text: 'Category', value: 'category', align: 'right' },
{ text: 'Dairy', value: 'dairy', align: 'right' },
],
desserts: [
{
name: 'Frozen Yogurt',
category: 'Ice cream',
dairy: 'Yes',
},
{
name: 'Ice cream sandwich',
category: 'Ice cream',
dairy: 'Yes',
},
...
],
}
},
})
Update
I can fix it with normal css like
<template v-slot:group.header="{items, isOpen, toggle}">
<th colspan="12">
<v-sheet>
<div #click="toggle" style="display: inline; width: 100vw">
<v-icon class="mr-3">{{ isOpen ? 'mdi-folder-open' : 'mdi-folder' }}</v-icon>
{{ items[0].folder }}
</div>
<div style="display: inline; float: right;">
<v-icon #click="deleteItem(item)">mdi-dots-vertical</v-icon>
</div>
</v-sheet>
</th>
</template>
```
But I wondering why Vuetify v-spacer is not working
v-spacer is basically just a div with the style flex-grow: 1. So to get this to work the parent container of the v-spacer needs to have display: flex.
In your case you can add this to v-sheet:
<v-sheet class="d-flex">
<!-- content -->
</v-sheet>
Here is my code. item.fav is initially false, but when I click on button it becomes true, I want color of icon to be purple when item.fav is true. But this is not working.
<template>
<v-container fluid>
<v-row>
<v-col v-for="(item, index) in items">
<v-btn icon #click='changeFav(item)'>
<v-icon :style='{color:`${fillcolor(item)}`}'>mdi-heart</v-icon>
</v-btn>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
....,
methods: {
fillcolor(item){
return item.fav ? 'purple' : 'orange';
},
changeFav(item){
item.fav=true;
},
}
</script>
I have also tried using class
.....
<v-icon class='{fillColor: item.fav}'>mdi-heart</v-icon>
.....
<style>
.fillColor {
color: 'purple';
}
</style>
when using a data variable as condition variable it works, but I cannot use it here as I'm having a loop.
What is that I'm doing wrong here or how can I do it better?
Take a look at Class and Style Bindings
Here is an example
<script setup>
import {ref} from 'vue'
const changeFav = (item) => {
item.fav = !item.fav;
}
const items = ref([
{name: "test1", fav: false},
{name: "test2", fav: false},
{name: "test3", fav: true},
{name: "test4", fav: false},
{name: "test5", fav: false},
{name: "test6", fav: false},
{name: "test7", fav: false},
])
</script>
<template>
<div v-for="(item, index) in items" :key="index" #click="changeFav(item)" >
<span :class="[item.fav ? 'orange' : 'purple']">
{{item.name}}
</span>
</div>
</template>
<style >
.purple {
color: purple;
}
.orange {
color: orange;
}
</style>
The problem with your code is that your fillcolor method needs to run on each click, but instead you are calling the changeFav method which only triggers the item.fav and the fillcolor method never runs.
So, You need to call that function too by changing your code to this:
<v-container fluid>
<v-row>
<v-col v-for="(item, index) in items" :key="index">
<v-btn icon #click="changeFav(item)">
<v-icon :style="{ color: `${fillcolor(item)}` }">mdi-heart</v-icon>
</v-btn>
</v-col>
</v-row>
</v-container>
export default {
....,
methods: {
fillcolor(item) {
return item.fav ? "purple" : "orange";
},
changeFav(item) {
item.fav = true;
return this.fillcolor(item)
},
},
}
================================================================
But I would prefer to do it like this:
<template>
<v-app>
<v-container fluid>
<v-row>
<v-col v-for="(item, index) in items" :key="index">
<v-btn icon #click="item.fav = !item.fav">
<v-icon :color="item.fav ? 'purple': 'red'">mdi-heart</v-icon>
</v-btn>
</v-col>
</v-row>
</v-container>
</v-app>
</template>
Although, it really depends on the way you are handling your data. For example, if you are using vuex then you should consider using mutations. I assumed you have the items and can handle them simply like this:
export default {
data: () => ({
items: [
{ name: "t1", fav: false },
{ name: "t2", fav: false },
{ name: "t3", fav: false },
{ name: "t4", fav: false },
{ name: "t5", fav: false },
{ name: "t6", fav: false },
{ name: "t7", fav: false },
],
}),
};
I want to put a status indicator in my v-expansion-panel-header:
v-expansion-panels
v-expansion-panel
v-expansion-panel-header Overview
v-expansion-panel-content
| ...
v-expansion-panel
v-expansion-panel-header(disable-icon-rotate)
v-icon(color="success") mdi-check
| Details
v-expansion-panel-content
However, for some reason the icon is taking up almost all the room in the header:
Is there a way to achieve this?
The Vuetify docs show an example with the check mark on the right hand side, by using v-slot:actions, but that had the same effect.
I note that there is a rule affecting the i of the icon:
.v-expansion-panel-header > :not(.v-expansion-panel-header__icon) {
flex: 1 1 auto;
}
Manually disabling that rule improves the situation:
Is there a way to do this properly?
Using Vuetify 2.5.8.
you can construct a grid layout inside v-expansion-panel-header using v-row and v-col to achieve any desired layout you want in the header.
check the demo below:
Vue.config.productionTip = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
items: [{
id: 1,
header: 'one',
icon: null,
iconColor: null,
content: 'some text'
},
{
id: 2,
header: 'two',
icon: 'mdi-check',
iconColor: 'green',
content: 'some other text'
},
]
}
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-main>
<v-container>
<v-expansion-panels focusable>
<v-expansion-panel v-for="item in items" :key="item.id">
<v-expansion-panel-header>
<v-row>
<v-col v-if="item.icon" cols="1">
<v-icon :color="item.iconColor">{{ item.icon }}</v-icon>
</v-col>
<v-col cols="11">
{{ item.header }}
</v-col>
</v-row>
</v-expansion-panel-header>
<v-expansion-panel-content>
{{ item.content }}
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</v-container>
</v-main>
</v-app>
</div>
how can I style my v-list-item-group if its in active-state?
<v-list>
<v-list-item-group v-model="day" color="green">
<v-list-item v-for="(item, i) in items" :key="i">
<v-list-item-content>
<v-list-item-title v-text="item.day"></v-list-item-title>
<v-list-item-title v-text="item.title"></v-list-item-title>
<v-list-item-subtitle v-text="item.date"></v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
I want something like this.
I already tried to style it in css but it doesn't change anything:
.v-list-group-active {
color: green;
}
option 1 - custom class
In general, it's better to add a class for the list (Otherwise these styles affect the entire page/site v-lists).
.red_list .v-list-item-group .v-list-item--active{
background-color: red;
color: white;
}
Snippet example:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
item: 1,
items: [
{ text: 'Real-Time', icon: 'mdi-clock' },
{ text: 'Audience', icon: 'mdi-account' },
{ text: 'Conversions', icon: 'mdi-flag' },
],
}),
})
.red_list .v-list-item-group .v-list-item--active{
background-color: red;
color: white;
}
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet"/>
<div id="app">
<v-app id="inspire">
<v-card
class="mx-auto"
max-width="300"
tile
>
<v-list class="red_list">
<v-subheader>REPORTS</v-subheader>
<v-list-item-group v-model="item" color="primary">
<v-list-item
v-for="(item, i) in items"
:key="i"
>
<v-list-item-icon>
<v-icon v-text="item.icon"></v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.js"></script>
option 2 - by color prop
More DRY approach.
<v-list-item-group v-model="item" color="red">
...rest of the code
Applies specified color to the control - it can be the name of material color (for example success or purple) or css color (#033 or rgba(255, 0, 0, 0.5)). You can find list of built in classes on the colors page
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{
icon: 'mdi-inbox',
text: 'Inbox',
},
{
icon: 'mdi-star',
text: 'Star',
},
{
icon: 'mdi-send',
text: 'Send',
},
{
icon: 'mdi-email-open',
text: 'Drafts',
},
],
model: 0,
}),
})
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet"/>
<div id="app">
<v-app id="inspire">
<v-card
class="mx-auto"
max-width="500"
>
<v-list>
<v-list-item-group v-model="model" color="red">
<v-list-item
v-for="(item, i) in items"
:key="i"
>
<v-list-item-icon>
<v-icon v-text="item.icon"></v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.js"></script>
So I just did this on v-list-item and not on v-list-group
.v-list-item--active {
background-color: red;
}
and it works.