Skip to content

Custom Actions ​

Intermediate

Manual control buttons with skip and restore functionality.

Demo ​

Source
vue
<script lang="ts" setup>
import { ref } from 'vue'
import { FlashCards } from 'vue3-flashcards'
import ActionButtons from './ActionButtons.vue'
import LearningCard from './LearningCard.vue'

const cards = ref([
  { id: 1, text: 'Business Strategy', description: 'Learn the fundamentals of strategic planning', icon: 'đŸ’ŧ' },
  { id: 2, text: 'Data Science', description: 'Master statistical analysis and machine learning', icon: '📊' },
  { id: 3, text: 'UI/UX Design', description: 'Create beautiful and intuitive user experiences', icon: '🎨' },
  { id: 4, text: 'Frontend Development', description: 'Build responsive and interactive web applications', icon: 'đŸ’ģ' },
  { id: 5, text: 'DevOps', description: 'Gain hands-on experience with DevOps tools and practices', icon: '🚀' },
])

const disableDrag = ref(false)
</script>

<template>
  <div class="w-full flex justify-center items-center py-20">
    <div class="max-w-sm w-full">
      <div class="mb-4 flex items-center justify-center">
        <label class="flex items-center space-x-2">
          <input
            v-model="disableDrag"
            type="checkbox"
            class="toggle toggle-primary"
          >
          <span>Disable Drag</span>
        </label>
      </div>

      <FlashCards :items="cards" :disable-drag="disableDrag">
        <template #default="{ item }">
          <LearningCard :item="item" />
        </template>

        <template #actions="{ approve, reject, restore, reset, isStart }">
          <ActionButtons
            :approve="approve"
            :reject="reject"
            :restore="restore"
            :reset="reset"
            :is-start="isStart"
          />
        </template>
      </FlashCards>
    </div>
  </div>
</template>
vue
<script setup lang="ts">
interface LearningItem {
  text: string
  description: string
  icon: string
}

defineProps<{
  item: LearningItem
}>()
</script>

<template>
  <div class="relative overflow-hidden rounded-2xl shadow-xl h-56 bg-white dark:bg-gray-800 transform transition-all duration-300 hover:shadow-2xl border dark:border-gray-700">
    <!-- Icon header -->
    <div class="absolute top-4 right-4 text-3xl">
      {{ item.icon }}
    </div>

    <!-- Content -->
    <div class="p-6 h-full flex flex-col justify-center">
      <h3 class="text-xl font-bold text-gray-800 dark:text-gray-100 mb-3">
        {{ item.text }}
      </h3>
      <p class="text-gray-600 dark:text-gray-300 text-sm leading-relaxed">
        {{ item.description }}
      </p>
    </div>

    <!-- Subtle decoration -->
    <div class="absolute bottom-0 left-0 w-full h-1 bg-gradient-to-r from-blue-500 to-purple-500" />
  </div>
</template>
vue
<script setup lang="ts">
defineProps<{
  approve: () => void
  reject: () => void
  restore: () => void
  reset: (options?: { animate?: boolean }) => void
  isStart: boolean
}>()
</script>

<template>
  <div class="grid grid-cols-2 gap-4 mt-6">
    <button
      class="px-6 py-3 bg-red-500 hover:bg-red-600 text-white rounded-xl font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 shadow-lg"
      @click="reject"
    >
      ❌ Skip
    </button>
    <button
      class="px-6 py-3 bg-emerald-500 hover:bg-emerald-600 text-white rounded-xl font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 shadow-lg"
      @click="approve"
    >
      ✅ Learn
    </button>
    <button
      class="px-6 py-3 bg-gray-500 hover:bg-gray-600 text-white rounded-xl font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 shadow-lg"
      :disabled="isStart"
      @click="restore"
    >
      â†Šī¸ Restore Last
    </button>
    <button
      class="px-6 py-3 bg-blue-500 hover:bg-blue-600 text-white rounded-xl font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 shadow-lg"
      @click="reset()"
    >
      🔄 Reset All
    </button>
    <button
      class="px-6 col-span-2 py-3 bg-blue-500 hover:bg-blue-600 text-white rounded-xl font-medium transition-all duration-200 transform hover:scale-105 active:scale-95 shadow-lg"
      @click="reset({ animate: true })"
    >
      🔄 Reset All Animated
    </button>
  </div>
</template>

Key Concepts ​

  • actions slot: Access { swipeLeft, swipeRight, restore, skip } methods
  • skip(): Move to next card without swipe event
  • restore(): Bring back the last swiped card
  • Perfect for: quiz apps, learning cards, manual controls

Released under the MIT License.