Search code examples
vuejs3vuetifyjs3

Vuetify - align v-btn right


How do I get the v-btn to align to the right side? My class="align-end" is not cutting it.

enter image description here

Vuetify Sandbox here

<template>
  <div>
    <v-list>
      <v-list-subheader>General</v-list-subheader>
      <div v-for="task in sortedTasks" :key="task.id">
        <v-list-item
          @click="doneTask(task.id)"
          :class="{ 'bg-color' : task.done }"
        >
          <template v-slot:prepend="{ isActive }">
            <v-list-item-action>
              <v-checkbox-btn :model-value="task.done"></v-checkbox-btn>
            </v-list-item-action>
            <v-list-item-title :class="{ 'task-complete' : task.done }">{{ task.title }}</v-list-item-title>

            <v-list-item-action class="align-end">
              <v-btn
              @click.stop="deleteTask(task.id)"
                icon flat>
                <v-icon color="primary lighten-1">mdi-delete</v-icon>
              </v-btn>
            </v-list-item-action>
          </template>
        </v-list-item>
        <v-divider></v-divider>
      </div>
    </v-list>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const tasks = ref([
  { id: 1, title: "Wake up", done: false },
  { id: 2, title: "Eat Banana", done: true },
  { id: 3, title: "Work", done: false },
  { id: 4, title: "Sleep", done: true },
]);

const doneTask = (id) => {
  const task = tasks.value.filter((task) => task.id === id)[0];
  if (task) {
    task.done = !task.done;
    //console.log("id: ", task.id); console.log("done: ", task.done);
  }
};

const deleteTask = (id) => {
  tasks.value = tasks.value.filter((task) => task.id !== id);
};

const sortedTasks = computed(() => {
  return [...tasks.value].sort((a, b) => (a.done === b.done) ? 0 : a.done ? 1 : -1);
});
</script>

<style>
.bg-color {
  background-color:rgb(224, 224, 232);
}
.task-complete {
  text-decoration: line-through;
}
.align-end {
  align-self: flex-end;
}
</style>

Solution

  • The prepend slot is meant for adding items before the input content. Use the append slot if you want to add items after. The actual input content technically shouldn't be in either slot.

    <v-list-item
      @click="doneTask(task.id)"
      :class="{ 'bg-color' : task.done }"
    >
      <v-list-item-title :class="{ 'task-complete' : task.done }">
        {{ task.title }}
      </v-list-item-title>
      <template v-slot:prepend="{ isActive }">
        <v-list-item-action>
          <v-checkbox-btn :model-value="task.done"></v-checkbox-btn>
        </v-list-item-action>
      </template>
      <template v-slot:append>
        <v-btn @click.stop="deleteTask(task.id)" icon flat>
          <v-icon color="primary lighten-1">mdi-delete</v-icon>
        </v-btn>
      </template>
    </v-list-item>
    

    updated sandbox