import { Signal } from "@preact/signals"; import type { Ingredient, IngredientGroup } from "@lib/recipeSchema.ts"; import { FunctionalComponent } from "preact"; import { unitsOfMeasure } from "@lib/parseIngredient.ts"; function formatAmount(num: number) { if (num === 0) return ""; return (Math.floor(num * 4) / 4).toString(); } function formatUnit(unit: string, amount: number) { const unitKey = unit.toLowerCase() as keyof typeof unitsOfMeasure; if (unitKey in unitsOfMeasure) { if (amount > 1 && unitsOfMeasure[unitKey].plural !== undefined) { return unitsOfMeasure[unitKey].plural; } if (unitKey !== "cup") { return unitsOfMeasure[unitKey].short; } return unitKey.toString(); } else { return unit; } } const Ingredient = ( { ingredient, amount, key = "", portion = 1 }: { ingredient: Ingredient; amount: Signal; key?: string | number; portion?: number; }, ) => { const { name, quantity, unit } = ingredient; const parsedQuantity = parseFloat(quantity); const finalAmount = (typeof parsedQuantity === "number" && amount) ? (parsedQuantity / portion) * (amount?.value || 1) : ""; return ( {formatAmount(finalAmount || 0)} {formatUnit(unit, finalAmount || 0)} {name} ); }; export const IngredientsList: FunctionalComponent< { ingredients: (Ingredient | IngredientGroup)[]; amount: Signal; portion?: number; } > = ( { ingredients, amount, portion }, ) => { return ( {ingredients.map((item, index) => { if ("items" in item) { // Render IngredientGroup const { name, items: groupIngredients } = item as IngredientGroup; return ( <> {groupIngredients.map((item, index) => { // Render Ingredient return ( ); })} ); } else { return ( ); } })}
{name}
); };