Skip to content

RecipeCard

Reworks meal-tracker's EinkaufenTab recipe-suggestion card (a dark card with a bright emerald pill CTA + pill time badge — a default-Tailwind-palette "vibe coded" tell, CLAUDE.md §1a) into a proper yemek component. The confirm button reuses MealReviewCard's checkmark-pulse + saving-spinner convention.

Playground

Skyr mit Beeren

Skyr-Beeren-Bowl

5 Min

Cremiger Skyr mit frischen Beeren und Honig.

220 kcal24g Protein
Zutaten
  • 250g Skyr
  • 1 Handvoll Beeren
  • 1 EL Honig
Zubereitungsschritte
  1. Skyr in eine Schüssel geben.
  2. Beeren waschen und darauf verteilen.
  3. Mit Honig beträufeln.
Bildnachweis: Foodie Factor

Click "Als Mahlzeit erfassen" — a checkmark pulses immediately, then the button shows a spinner (simulating a ~1.2s save call). Omit imageUrl/ingredients/instructions/photoCreditLabel for a minimal card (e.g. a recipe idea with no image yet).

vue
<script setup>
import { RecipeCard } from 'yemek'

const saving = ref(false)

async function logRecipe(recipe) {
  saving.value = true
  await saveMeal(recipe)
  saving.value = false
}
</script>

<template>
  <RecipeCard
    v-for="recipe in generatedAlternatives"
    :key="recipe.title"
    :title="recipe.title"
    :description="recipe.description"
    :prep-time="recipe.prepTime"
    :calories="Math.round(recipe.caloriesEstimate || 0)"
    :protein="Math.round(recipe.proteinEstimateG || 0)"
    :image-url="recipe.imageUrl"
    :image-alt="recipe.title"
    :ingredients="recipe.ingredients"
    ingredients-label="Zutaten"
    :instructions="recipe.instructions"
    instructions-label="Zubereitungsschritte"
    :photo-credit-label="recipe.photographer ? `Bildnachweis: ${recipe.photographer}` : undefined"
    :photo-credit-url="recipe.photoUrl"
    confirm-label="Als Mahlzeit erfassen"
    :saving="saving"
    @confirm="logRecipe(recipe)"
  />
</template>

Props

PropTypeDefaultDescription
titlestringRecipe title.
descriptionstringundefinedShort recipe description.
prepTimestringundefinedAlready-formatted, e.g. "10 Min" — no time-estimation math in the kit.
caloriesnumberEstimated calories.
proteinnumberEstimated protein (g).
imageUrlstringundefinedRecipe photo. Card renders without an image section if omitted.
imageAltstring''Alt text for the image.
ingredientsstring[][]Ingredient lines. Section only renders when non-empty.
ingredientsLabelstring'Ingredients'Already-localized section label.
instructionsstring[][]Instruction steps. Section only renders when non-empty.
instructionsLabelstring'Instructions'Already-localized section label.
photoCreditLabelstringundefinedAlready-formatted, e.g. "Bildnachweis: Foodie Factor". Credit line only renders when set.
photoCreditUrlstringundefinedLink target for the credit line.
confirmLabelstringConfirm button label.
savingbooleanfalseDisables the button and shows a spinner while the consumer's save call is in flight.

Events

EventPayloadFired when
confirmThe confirm button is clicked (not fired while saving is true).

Behavior notes

  • No recipe-generation/ingredient-matching logic lives here — the consumer's own AI call already produced the recipe fields; this only renders and reuses MealReviewCard's confirm-button micro-interaction (checkmark-pulse, then saving's spinner).
  • protein uses a colored dot (--yemek-nutrient-protein) next to neutral text, not colored text itself — same lesson as MealEntry's macro legend (coloring the letters directly read unclear at small sizes). calories stays the bold accent-colored headline number.
  • The card fades/slides in on mount; the image itself cross-fades in on load rather than popping in abruptly once its network request resolves.
  • The time badge is one of the kit's few intentional pill shapes (--yemek-radius-full) — a small standalone badge is the semantically-right case per TOKENS.md §Form, unlike the confirm button (--yemek-radius-sm, deliberately sharper, same rule as MealReviewCard's).
  • prefers-reduced-motion: reduce disables the card/image entrance transitions and the checkmark-pulse/pop animations, and slows the spinner's rotation instead of stopping it (it's a loading indicator, not decorative).