Vuetify stepper text overflow - css

I have an issue with the stepper component in the Vuetify framework where the text labels for the steps overlap in IE11. See codepen below:
https://codepen.io/thorne51/pen/mjdQXb
HTML
<div id="app">
<v-app id="inspire">
<v-container>
<v-stepper v-model="e1" :alt-labels="true">
<v-stepper-header>
<template v-for="(step, index) in steps">
<v-stepper-step :step="step.stepNr">{{ step.label }}</v-stepper-step>
<v-divider v-if="index + 1 < steps.length"></v-divider>
</template>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content v-for="(step, index) in steps" :step="step.stepNr" :key="index">
{{ step.stepNr }}. {{ step.label }}
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</v-container>
</v-app>
</div>
JS
new Vue({
el: '#app',
data () {
let steps = [];
for (let i = 0; i < 10; i++) {
steps.push({
label: 'regular driver\'s personal details',
stepNr: i + 1,
});
}
return {
e1: 0,
steps: steps,
}
}
})
CSS
.v-stepper__step {
flex: 1 1;
}

Easy. Just remove the flex: 1 1; from the v-stepper__step class.

Related

Vue.3 does not render Vuetify components when using at tag attribute in transition-group

I want to animate some cards using gsap for the following components in Vue.js 3.
<script setup lang="ts">
import gsap from 'gsap'
import { useTranslate } from '#/#core/composable/useTranslate'
import TimeLineItem from './TimeLineItem.vue'
interface ITimeLine {
icon: string
title: string
description: string
color: string
}
const timeLines = ref<ITimeLine[]>([
{
title: 'PadvishInstall',
description: 'timeline-welcome',
icon: 'material-symbols:looks-one-outline',
color: 'warning',
},
{
title: 'InsertingToken',
description: 'timeline-step1',
icon: 'ic:outline-looks-two',
color: 'error',
},
{
title: 'ContactInfo',
description: 'timeline-step2',
icon: 'ph:number-square-three-bold',
color: 'info',
},
])
const { translate } = useTranslate()
/**
* Functions
*/
const beforeEnter = (el: Element) => {
const he = el as HTMLElement
he.style.opacity = '0'
he.style.transform = 'translateX(100px)'
}
const enter = (el: Element, done: () => void) => {
const he = el as HTMLElement
gsap.to(el, {
opacity: 1,
x: 0,
duration: 0.8,
onComplete: done,
delay: Number((el as HTMLElement).dataset.index) * 0.5,
})
}
</script>
<template>
<VCard class="text-center" variant="text" title="card title">
<VCardText>
<transition-group
align="start"
justify="center"
truncate-line="both"
:density="$vuetify.display.smAndDown ? 'compact' : 'default'"
appears
#before-enter="beforeEnter"
#enter="enter"
tag="v-timeline"
>
<TimeLineItem
v-for="(item, index) in timeLines"
:key="index"
:data-index="index"
:title="translate(item.title)"
:description="translate(item.description)"
:icon="item.icon"
:color="item.color"
/>
</transition-group>
</VCardText>
</VCard>
</template>
TimeLineItem component :
<script setup lang="ts">
interface Props {
icon: string
title: string
description: string
color: string
}
const props = defineProps<Props>()
</script>
<template>
<VTimelineItem size="x-small" fill-dot>
<template #icon>
<div class="v-timeline-avatar-wrapper rounded-circle">
<VAvatar size="small">
<VIcon size="100" :icon="icon" :color="color" />
</VAvatar>
</div>
</template>
<VCard>
<VCardText>
<!-- 👉 Header -->
<div class="d-flex justify-space-between">
<h6 class="text-base font-weight-semibold mb-1 me-3">
{{ title }}
</h6>
</div>
<!-- 👉 Content -->
<p class="mb-1">
{{ description }}
</p>
</VCardText>
</VCard>
</VTimelineItem>
</template>
<style lang="scss" scoped>
.v-timeline-avatar-wrapper {
background-color: rgb(var(--v-theme-background));
}
</style>
For animating each element of v-timeline, I used transition-group and set the value of tag to v-timeline. But, when using transition-group, the Vue does not recognize the 'v-timeline' is a vuetify component and must render a component!.
This is a limitation of transition-group or can be considered as a bug in Vue.3?

vuedraggable custom style for each individual item

I need to have each vuedraggable item to have different styling in the wrapper tag (for example based on the element's index) like so:
<div class="wrapper">
<div class="grid_item" style="grid-row: 1">
I am Item 1
</div>
<div class="grid_item" style="grid-row: 2">
I am Item 2
</div>
<div class="grid_item" style="grid-row: 3">
I am Item 3
</div>
</div>
I know this is a very simple example that doesn't really need the index but suppose a more complex scenario where it is necessary to have access to the index in the draggable component (not its child template).
Suppose the current component looks like this:
<template>
<div class="wrapper">
<draggable
:list="items"
class="grid_item"
item-key="name">
<template #item="{ element }">
I am {{ element.name }}
</template>
</draggable>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
components: {
draggable,
},
data() {
return {
items: [
{
name: 'Item 1'
},
{
name: 'Item 2'
},
{
name: 'Item 3'
},
],
}
},
methods: {
rowForItem(index) {
return `grid-row: ${index + 1}`;
}
},
}
</script>
<style>
.wrapper {
display: grid;
}
.grid_item {
background-color: gray;
}
</style>
How can I make use of the rowForItem method here?

How to change icon on hover effect?

As an user, I want to see tasks checkbox as gray tick on hover and blue tick when checkbox is checked.
<div id="app">
<v-app id="inspire">
<v-container
class="px-0"
fluid
>
<v-checkbox
:off-icon="'mdi-circle-outline'"
:on-icon="'mdi-check-circle'"
v-model="checkbox"
:label="`Checkbox 1: ${checkbox.toString()}`"
></v-checkbox>
</v-container>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
checkbox: true,
}
},
})
https://codepen.io/edlung/pen/WNdmKBL?editors=101
As already mentioned in comments, you can use v-hover component to achieve it:
<v-hover
v-slot="{ hover }"
>
<v-checkbox
:off-icon="'mdi-circle-outline'"
:on-icon="'mdi-check-circle'"
v-model="checkbox"
:label="`Checkbox 1: ${checkbox.toString()}`"
:color="hover ? 'gray': 'primary'"
/>
</v-hover>
...
data () {
return {
checkbox: true,
}
}
CodePen demo is here

How to arrange elements in Vuejs component

I have a component in Vue like this:
Tags.vue
<template>
<div>
<v-chip
v-for="tag in tags"
:key="tag"
class="ma-2"
label
x-small
color="blue"
text-color="white"
>
{{ tag }}
</v-chip>
</div>
</template>
<script>
export default {
name: 'Tags',
props: {
tags: {
type: Array,
default: () => ['Empty'],
},
},
}
</script>
This is the result
How can I make them appear one below the other instead of side by side?
This should be a css questions. Add a class "container" for the wrapper div and put some css into it. You can use flex-box
<div class="container">
<v-chip
v-for="tag in tags"
:key="tag"
class="ma-2"
label
x-small
color="blue"
text-color="white"
>
{{ tag }}
</v-chip>
</div>
<style lang="scss" scoped>
.container{
display: flex,
flex-direction: 'column'
}
</style>
This is another solution without css:
I use tag https://vuetifyjs.com/en/components/chip-groups/
<template>
<div class="container">
<v-chip-group column active-class="primary--text">
<v-chip
v-for="tag in tags"
:key="tag"
class="ma-2"
outlined
x-small
color="blue"
text-color="blue"
>
{{ tag }}
</v-chip>
</v-chip-group>
</div>
</template>
<script>
export default {
name: 'Tags',
props: {
tags: {
type: Array,
default: () => ['Empty'],
},
},
}
</script>

How can I add conditional style in Vue.js?

I want to add a conditional style in my Component.
My component is below:
<site-pricing
color="primary"
currency="$"
price="25"
to="/purchase"
>
<template v-slot:title>Complete</template>
<template v-slot:desc>{{ $t('plans.completeDesc' )}}</template>
<template v-slot:planSuffix>/ {{ $t('plans.oneTime' )}}</template>
<template v-slot:features>
<ul>
<li>{{ $t('plans.xchats', [ 200 ] )}}</li>
<li>{{ $t('plans.sDomain' )}}</li>
</ul>
</template>
<template v-slot:footer>{{ $t('plans.oneTime' )}}</template>
</site-pricing>
I want to add a special style just like, if 'color = primary', then add a border-top: 5px red...
You should use the conditional style binding for vue. I'll show an example:
new Vue({
el: '#app',
data: {
color: "secondary"
},
methods: {
toggleColor(val) {
this.color = val
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div :style="[color==='primary' ? {color: 'red'} : {color: 'blue'}]">Primary</div>
<div :style="[color==='secondary' ? {color: 'red'} : {color: 'blue'}]">Secondary</div>
<button #click="(e) => toggleColor('primary')">Switch to pirmary</button>
<button #click="(e) => toggleColor('secondary')">Switch to secondary</button>
</div>

Resources